[英]Array of child component not being re-rendered if param in parent changes
我是 React 的新手。 我必须实现一个按钮,在每次单击按钮时在页面上添加几个字段(文本框、选择、复选框)。 我通过参考示例http://jsfiddle.net/rpd32h1g/实现了这一点。 我有 3 个类 1. 父类,我在其中编写了填充 subSectionList 的逻辑,它定义了单击按钮时需要添加的组件/字段。 2. 子组件(AddAccount.js),它从父组件接收参数 subSectionList 并将其传递给子子组件 Account.js 的数组。 这个数组是在点击按钮时创建的,每次点击都会更新数组。 3. 子子组件(Account.js),它接收参数 subSectionList 并迭代它以显示所需的组件。 问题:如果在父级中更改 subSectionList 的值,则不会重新渲染子子子 Account.js。 下面是代码供参考:
调用下面的函数(findApplicableFields) onChange 使用按钮添加的字段(此方法存在于父类中)。
const findApplicableFields = (questions, questionName, optionName, currentQuestion) => {
const newSubSectionList = questions.map(question => {
if (question.name === questionName) {
return { ...question, children };
}
return { ...question };
});
subSectionList[questionName] = newSubSectionList;
}
下面是孩子的代码片段:
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import Account from './Account';
export default function AddAccount({
buttonText,
type = 'button',
buttonClass,
questions,
checkoutJourney,
handleBlur,
isValid,
question,
onChange,
subSectionList,
...rest
}) {
const [addAccount, setAddAccount] = useState(true);
const [accountArray, setAccountArray] = useState(
checkoutJourney['addAccountArray'] == null ? [] : checkoutJourney['addAccountArray']
);
let i = 0;
const _onClick = e => {
e.preventDefault();
setAddAccount(true);
setAccountArray([
<Account
key={i}
questions={questions}
checkoutJourney={checkoutJourney}
handleBlur={handleBlur}
onChange={onChange}
isValid={isValid}
questionName={question.name}
subSectionList={subSectionList}
{...rest}
/>,
...accountArray
]);
checkoutJourney['addAccountArray'] = accountArray;
checkoutJourney['subSectionList'] = subSectionList;
i++;
};
return (
<>
{addAccount ? accountArray : null}
<div className={buttonClass}>
<button
className="button button--dark button--primary"
type={type}
onClick={e => {
_onClick(e);
}}
>
{buttonText}
</button>
</div>
</>
);
}
AddAccount.propTypes = {
_onClick: PropTypes.func,
type: PropTypes.string,
buttonText: PropTypes.string,
buttonClass: PropTypes.string,
questions: PropTypes.array,
onChange: PropTypes.func,
checkoutJourney: PropTypes.object,
rest: PropTypes.object,
handleBlur: PropTypes.func,
isValid: PropTypes.object,
question: PropTypes.any,
subSectionList: PropTypes.object
};
AddAccount.defaultProps = {
buttonText: '+ Add another account'
};
下面是需要重新渲染的子孩子的代码片段:
import React from 'react';
import PropTypes from 'prop-types';
import TextInput from '../TextInput/WS2TextInput';
import Select from '../Select/WS2Select';
import AddressMoreServices from '../AddMoreServices/AddMoreServices';
import Checkbox from '../Checkbox/Checkbox';
const Account = ({ checkoutJourney, handleBlur, isValid, onChange, subSectionList, questionName, ...rest }) => {
return (
<>
{subSectionList[questionName].map((question, i, questions) => {
//The logic to render the field based on type of question
})}
</>
);
}
Account.propTypes = {
questions: PropTypes.array,
onChange: PropTypes.func,
checkoutJourney: PropTypes.object,
rest: PropTypes.object,
handleBlur: PropTypes.func,
isValid: PropTypes.object,
subSectionList: PropTypes.object,
questionName: PropTypes.string
};
export default Account;
发生这种情况是因为您没有更改subSectionList
变量,而是操作其内容(在对象中添加和删除属性)。 React 只会在Components
必须完全改变的变量(换句话说,它们在内存中交换)时重新渲染Components
。 React 通过在旧状态变量和新状态变量之间执行浅层比较来识别更改。 在您的情况下,变量subSectionList
始终相同(因为您只是向其添加属性),因此 React 不会重新渲染<AddAccount />
和<Account />
。
为了重新渲染<AddAccount />
和<Account />
你必须通过在你的父组件中调用setState
来重新创建整个subSectionList
:
const [subSectionList, setSubSectionList] = useState([]);
setSubSectionList([
...subSectionList,
[questionName]: newSubSectionList
]);
这将在内存中生成一个全新的subSectionList
数组,使 React 重新渲染所有依赖于它的组件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.