#reactjs
#reactjs
Вопрос:
Дочерний компонент визуализируется, даже если его реквизиты не изменены. Ниже приведен родительский компонент
import Child from "./Child";
function Parent({
selected,
show,
setShow,
}) {
const [isRunNow, setIsRunNow] = useState(true);
const [isNotifyMe, setIsNotifyMe] = useState(false);
const handleNotify = useCallback(() => {
setIsNotifyMe(!isNotifyMe);
}, [isNotifyMe]);
const handleSchedule = useCallback(() => {
setIsRunNow(!isRunNow);
}, [isRunNow]);
const WindowForm = () => {
return (
<div>
<Row>
<Col span={12}>
<label className={styles.labelWeight}> Name : </label>
<input
type="text"
value={selected.name}
readOnly={true}
className={styles.input}
/>
<br></br>
<br></br>
<label className={styles.labelWeight}>Description : </label>
<input
type="text"
value={selected.description}
readOnly={true}
className={styles.input}
></input>
<br></br>
<br></br>
<input
type="checkbox"
name="runImm"
id="runImm"
checked={isRunNow}
onChange={handleSchedule}
></input>
<label> Schedule as soon as possible</label>
</Col>
<Col span={12}>
<input
type="checkbox"
name="notifyProcess"
id="notifyProcess"
checked={isNotifyMe}
onChange={handleNotify}
></input>
<label> Notify me when this process ends</label>
<br></br>
<br></br>
<label>Submission Notes : </label>
<textarea
name="notes"
id="notes"
rows="4"
cols="50"
disabled={!isNotifyMe}
></textarea>
</Col>
</Row>
<Row>
<Col span={24}>
<Child isRunNow={isRunNow} />
</Col>
</Row>
</div>
);
};
return (
<Modal
visible={show}
width={800}
centered
maskClosable={false}
onCancel={() => setShow(false)}
title="JKM"
>
<WindowForm />
</Modal>
);
}
Дочерний компонент выглядит следующим образом:
import Uploader from "./Uploader";
import Downloader from "./Downloader";
const { TabPane } = Tabs;
const areEqual = (prevProps, nextProps) => {
console.log("passed here"); // THIS IS NEVER LOGGED!!
return true;
};
function Child({ isRunNow }) {
console.log(
`Rendering Childe component...isRunNow value : ${isRunNow}`
);
return (
<div>
<Tabs defaultActiveKey="ka">
<TabPane tab="ka" key="ka">
Panel
</TabPane>
<TabPane tab="sa" key="sa" disabled={isRunNow}>
<Downloader />
</TabPane>
<TabPane tab="da" key="da">
<Uploader />
</TabPane>
</Tabs>
</div>
);
}
export default React.memo(Child, areEqual);
Когда я устанавливаю или снимаю флажок Уведомлять меня, дочерний компонент дочернего компонента каждый раз повторно отображается. Кажется, что реквизиты не равны и, следовательно, их повторное воспроизведение. Я не мог понять, где что-то не так.
Пожалуйста, подскажите, где я делаю неправильно.
Комментарии:
1. это происходит каждый раз, когда вы нажимаете флажок с именем runImm?
2. Да, когда я устанавливаю или снимаю флажок с именем notifyProcess, дочерний компонент повторно отображается. Хотя флажок notifyProcess не имеет ничего общего со свойствами дочернего компонента
Ответ №1:
Я предлагаю вам отделить WindowForm от компонента, кажется, что это проблема. когда я использую его как компонент, memo начинает работать, я думаю, это связано с тем, что это функция, которая возвращает компонент, поэтому она отображает его, несмотря ни на что.
решение: переместите WindowForm за пределы компонента и создайте с ним новый, а затем вызовите его, и он будет работать нормально
const WindowForm = () => {
return (
<div>
<Row>
<Col span={12}>
<label className={styles.labelWeight}> Name : </label>
<input
type="text"
value={selected.name}
readOnly={true}
className={styles.input}
/>
<br></br>
<br></br>
<label className={styles.labelWeight}>Description : </label>
<input
type="text"
value={selected.description}
readOnly={true}
className={styles.input}
></input>
<br></br>
<br></br>
<input
type="checkbox"
name="runImm"
id="runImm"
checked={isRunNow}
onChange={handleSchedule}
></input>
<label> Schedule as soon as possible</label>
</Col>
<Col span={12}>
<input
type="checkbox"
name="notifyProcess"
id="notifyProcess"
checked={isNotifyMe}
onChange={handleNotify}
></input>
<label> Notify me when this process ends</label>
<br></br>
<br></br>
<label>Submission Notes : </label>
<textarea
name="notes"
id="notes"
rows="4"
cols="50"
disabled={!isNotifyMe}
></textarea>
</Col>
</Row>
<Row>
<Col span={24}>
<Child isRunNow={isRunNow} />
</Col>
</Row>
</div>
);
};
этот компонент и его состояние преобразуйте в новый компонент, и все начнет работать
Комментарии:
1. Спасибо. Это сработало. Но до сих пор неясно, как сработало перемещение компонента наружу. Любые комментарии были бы полезны для понимания проблемы.
2. ну, я сам не уверен, я думаю, это потому, что вы отправляете функцию, которая повторяется каждый раз, когда вы повторно изменяете компонент по изменению и значению, затем она снова и снова печатает функцию, независимо от заметки. возможно, вы можете попробовать использовать useCallback
3. @BNK после небольшого чтения это произошло потому, что вы отправляете функцию, которая повторяется каждый раз, когда вы меняете состояние. в отличие от usecallback, который блокирует эти данные, если они не соответствуют зависимостям