React useState 钩子不会触发子组件的重新渲染

Jon*_*y B 4 javascript reactjs react-hooks

我有一个父功能组件<EditCard/>,它是在选择编辑表行按钮时打开的模态。此编辑卡包含一个名为的状态变量data,该变量由正在编辑的表行中的数据组成。我正在<EditCard/>使用useState钩子设置/修改状态。

<EditCard/>有一个子组件<CategoryDropdown/>,它是一个下拉列表,它接受一个 propdata.assignCategory作为它的选定值,还有一个回调handleChange(),它data用从下拉列表中选择的值更新状态值。

当我从下拉列表中选择一个新值时,会handleChange()被调用并被setData()调用,我看到状态正在更新,但<CategoryDropdown/>没有使用新的选定值重新呈现。

编辑卡组件代码

export default function EditCard(props) {
    const [data, setData] = useState(props.data);

    const handleChange = () => event => {
        let d = data;
        d.assignCategory = event.target.value;
        setData(d);
    };

    let assignCategoryCol = data.assignCategory !== undefined ? <AssignCategoryCol data={data} handleChange={handleChange}/> : <></>;

    return (
        <div>
            {assignCategoryCol}
            <Button>Update</Button>
        </div>
    )
}

{props.data.bucketTotal}`} <Lock/></Typography>)
};

const AssignCategoryCol = (props) => {
    return (
        <CategoryDropdown id={props.data.id} assignedCategory={props.data.assignCategory} handleDropdownChange={props.handleChange}/>)
};

const useStyles = makeStyles(theme => ({}));
Run Code Online (Sandbox Code Playgroud)

类别下拉组件

class CategoryDropdown extends Component {
    constructor(props) {
        super(props);
        //TODO Get Categories from DB and set default
        this.state = {
            categories: ['Select One', 'Category1', 'Category2', 'Category3'],
        };
    }

    render() {
        return (
            <div id={'categoryDropdown'}>
                <Select onChange={this.props.handleDropdownChange(this.props.id)} value={this.props.assignedCategory}>
                    {this.state.categories.map((category) => {
                        return <MenuItem value={category}>{category}</MenuItem>
                    })}
                </Select>
            </div>
        )
    }
}


const styles = theme => ({});

export default withStyles(styles)(CategoryDropdown)
Run Code Online (Sandbox Code Playgroud)

Mai*_*iya 16

为了让 React 知道状态中的某些内容发生了变化,您需要用一个全新的对象替换当前对象。目前,react 认为它是同一个对象,所以什么都不做。它不会搜索对象以查看其中的任何属性是否已更改。

在您的 handleChange 事件处理程序中,您有:

let d = data;
Run Code Online (Sandbox Code Playgroud)

这不是复制数据对象。相反,现在变量“d”指向变量“data”指向的同一个对象(在内存中)。

(有关更多信息,请阅读“按引用传递”与“按值传递”)。

要解决这个问题,请参阅下面的解构/复制:

const [data, setData] = useState(props.data)

const handleChange = event => {
        let newData = {...data} //copy the object
        newData.assignCategory = event.target.value;
        setData(newData);
 };
Run Code Online (Sandbox Code Playgroud)