Как синхронизировать реквизиты в состояние с помощью React hook: setState()
Я пытаюсь установить состояние с помощью React-хука setState(), используя реквизиты, которые получает компонент. Я пытался использовать следующий код:
import React,{useState , useEffect} from 'react';
const Persons = (props) => {
// console.log(props.name);
const [nameState , setNameState] = useState(props)
console.log(nameState.name);
console.log(props.name);
return (
<div>
<p>My name is {props.name} and my age is {props.age}</p>
<p>My profession is {props.profession}</p>
</div>
)
}
export default Persons;
Проблема в том, что состояние устанавливается при загрузке компонента. Но когда он получает новые реквизиты, состояние не обновляется. Как обновить состояние в этом случае? Заранее спасибо.
Ответы
Ответ 1
useState
Аргумент функции ловушек используется только один раз, а не каждый раз, когда изменяется реквизит. Вы должны использовать ловушки useEffect
для реализации того, что вы бы назвали функциональностью componentWillReceiveProps/getDerivedStateFromProps
import React,{useState , useEffect} from 'react';
const Persons = (props) => {
const [nameState , setNameState] = useState(props)
useEffect(() => {
setNameState(props);
}, [props])
return (
<div>
<p>My name is {props.name} and my age is {props.age}</p>
<p>My profession is {props.profession}</p>
</div>
)
}
export default Persons;
Ответ 2
Для этого вам нужно использовать useEffect
чтобы ваш код выглядел следующим образом. Так как вы хотите избежать повторного рендеринга, если плюсы не изменились, вы должны сначала проверить useEffect, а затем установить для реквизитов текущую переменную.
import React, { useState, useEffect } from "react";
const Persons = props => {
// console.log(props.name);
const [nameState, setNameState] = useState(props);
console.log(nameState.name);
console.log(props.name);
useEffect(
() => {
if (nameState !== props.name) {
setNameState(props.name);
}
},
[nameState]
);
return (
<div>
<p>
My name is {props.name} and my age is {props.age}
</p>
<p>My profession is {props.profession}</p>
</div>
);
};
export default Persons;
демонстрация
Ответ 3
import React, { useState, useEffect } from "react";
const Persons = props => {
// console.log(props.name);
const [nameState, setNameState] = useState(props);
console.log(nameState.name);
console.log(props.name);
useEffect(
() => {
if (nameState !== props) {
setNameState(props);
}
},
[nameState]
);
return (
<div>
<p>
My name is {props.name} and my age is {props.age}
</p>
<p>My profession is {props.profession}</p>
</div>
);
};
export default Persons;
Согласно документу "Реакция хуков", все время, когда какой-либо реквизит обновляется или есть какое-либо обновление в компоненте, тогда вызывается useEffect. Таким образом, вам нужно проверить условие перед обновлением useState, а затем обновить свое значение, чтобы оно не выполняло повторную визуализацию
Ответ 4
Эту общую идею можно поставить на крючок:
export function useStateFromProp(initialValue) {
const [value, setValue] = useState(initialValue);
useEffect(() => setValue(initialValue), [initialValue]);
return [value, setValue];
}
function MyComponent({ value: initialValue }) {
const [value, setValue] = useStateFromProp(initialValue);
return (...);
}