繁体   English   中英

如果父组件中的参数更改,则不会重新渲染子组件数组

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM