помогите найти ошибку hook useEffect
Пытаюсь вникнуть в хуки и переписываю этот класс.Этот класс получает от класса выше пропсы getData - fetch запрос к API, itemId - айдишник в списке, по которому кликнул пользователь, по дефолту приходит null и филды
const Field = ({item, field, label}) => {
return (
<li className="list-group-item d-flex justify-content-between">
<span className="term">{label}</span>
<span>{item[field]}</span>
</li>
)
}
которые рендерят содержимое.
export default class ItemDetails extends Component {
state = {
item: null,
loading: true,
error: false
}
componentDidMount() {
this.updateItem();
}
componentDidUpdate(prevProps) {
if (this.props.itemId !== prevProps.itemId) {
this.updateItem();
}
}
onItemDetailsLoaded = (item) => {
this.setState({
item,
loading: false
})
}
updateItem() {
const {itemId} = this.props;
if (!itemId) {
return;
}
this.setState({
loading: true
})
this.props.getData(itemId)
.then( this.onItemDetailsLoaded )
.catch( () => this.onError())
}
onError(){
this.setState({
item: null,
error: true
})
}
render() {
if (!this.state.item && this.state.error) {
return <ErrorMessage/>
} else if (!this.state.item) {
return <span className="select-error">Please select a character</span>
}
const {item} = this.state;
const {name} = item;
if (this.state.loading) {
return (
<div className="char-details rounded">
<Spinner/>
</div>
)
}
return (
<div className="char-details rounded">
<h4>{name}</h4>
<ul className="list-group list-group-flush">
{
React.Children.map(this.props.children, (child) => {
return (React.cloneElement(child, {item}))
})
}
</ul>
</div>
);
}
}
Получилось следующее
function ItemDetails(props) {
const [item, itemUpdate] = useState({});
useEffect(() => {
if (!props.itemId) {
return;
}
props.getData(props.itemId)
.then(data => {
itemUpdate(data);
}, (error) => {
console.log(error);
})
}, [])
console.log(props.itemId);
if (!item) {
return <span className="select-error">Please select a character</span>
}
const {name} = item;
return (
<div className="char-details rounded">
<h4>{name}</h4>
<ul className="list-group list-group-flush">
{
React.Children.map(props.children, (child) => {
return (React.cloneElement(child, {item}))
})
}
</ul>
</div>
);
}
Проблема заключается в том, что на классах все работало и рендерилось. Сейчас же, если я захардкодил itemId, то он отображает то, что нужно мне. Если я передаю в fetch itemId через пропсы, то ничего не рендерится. Сам itemId приходит, через консоль я его вывожу, но почему-то ничего не работает. Если в useEffect я убираю [] как второй аргумент, то все рабоатет, но идут утечки информации. Гуглил что нужны квадратные скобки чтобы их убрать, но тогда все перестает работать.
Ответы (1 шт):
Второй аргумент в useEffect (да и в большинстве хуков, про все не могу ручаться) это зависимости. Хук следит за зависимостями и "дёргается" только в том случае, если значение поменялось.
useEffect(() => {
if (!props.itemId) {
return;
}
props.getData(props.itemId)
.then(data => {
itemUpdate(data);
}, (error) => {
console.log(error);
})
}, [props.itemId]) // обновить только если itemId поменялся