【问题标题】:Update state with two functions, doesn't update component correctly使用两个函数更新状态,不能正确更新组件
【发布时间】:2018-01-16 11:10:27
【问题描述】:

我有一个包含两个函数的组件,它们应该更新状态对象:

class Categories extends Component {
constructor(props) {
    super(props);
    this.state = {
        data: [],
        categoryData: [],
        objects: [],
        object:[],
    };
}
componentDidMount() {
    this.setState({
        data:data.Dluga,
        categoryData: data.Dluga.basic,
        objects:data,
    })
}
changeCategory(event) {
    event.preventDefault();
    this.setState({
        categoryData: this.state.data[(event.currentTarget.textContent).split(' ')[1]],
    });
}
changeObject(event) {
    event.preventDefault();
    const objectOne = Object.assign({}, this.state.objects[event.currentTarget.parentElement.parentElement.children[0].children[0].value]);
    this.setState({
        objects: this.state.objects,
        object:objectOne,
    });

};
render() {
    return (
        <div className='categories'>
            <SelectObejct onValueChange={this.changeObject}/>
            <ul>
                {Object.keys(this.state.data).map((item) => {
                    return (
                        <li className='category' key={item}
                            onClick={this.changeCategory.bind(this)}>
                            <span className='category-item'> {item}</span>
                        </li>
                    )})
                }
            </ul>
            <div>
                <CategoryData categoryData={this.state.categoryData}/>
            </div>
        </div>
    );
}
}

当我使用 changeObject 更新状态时,我在状态对象中有两个属性:objectsobject,但最初是 4 个属性...接下来,当我使用 changeCategory 更新状态时,我的初始属性来自componentDidMount 并更新了 categoryDataobject 为空...我无法在一个函数中更新状态,因为它是两个 onClick 元素。我应该怎么做才能正确更新状态?

【问题讨论】:

  • componentDidMount data 来自哪里?
  • 另请注意,上面的语法错误会阻止它运行(changeObject 的方法主体结束后的;)。 (如果那是您的真实代码并且您正在转译并且转译器让您侥幸逃脱 ;,请在转译器项目中提交有关它的错误。)
  • 抱歉,这个组件没有多大意义……你能在沙箱中创建它吗……比如codesandbox.io?

标签: javascript reactjs state


【解决方案1】:

您做错的主要事情是根据现有状态更新状态,而不使用setState 的回调版本。状态更新可以是异步的,并且可以组合(批量)。每当您设置从当前状态派生的状态时,您must use the callback form。例如:

changeCategory(event) {
    event.preventDefault();
    this.setState(prevState = > {
        return {
            categoryData: prevState.data[(event.currentTarget.textContent).split(' ')[1]]
        };
    });
}

请注意,我们向它传递了一个函数,该函数将在稍后调用(只是稍晚一点,但稍后),并将获取当时的当前状态作为参数传递给它;我们将新状态作为返回值返回。

当我使用 changeObject 更新状态时,我在状态对象中有两个属性:objectsobject,但最初它是 4 个属性...

这很正常。在调用setState 时,通常只指定状态属性的子集。其实changeObject应该是:

changeObject(event) {
    event.preventDefault();
    this.setState(prevState => {
        const objectOne = Object.assign({}, prevState.objects[event.currentTarget.parentElement.parentElement.children[0].children[0].value]);
        return { object: objectOne };
    });
}

请注意,我没有指定 objects: prevState.objects。如果你不改变它就没有理由。

接下来,当我使用changeCategory 更新状态时,我有来自componentDidMount 的初始属性并更新了categoryDataobject 是空的。

object 仅在您将其设置为空时才会为空(无论“空”是什么意思)。我怀疑解决上述问题将解决此问题,但如果不是,并且如果您无法通过进一步调试解决问题,我建议发布一个 new 问题,并使用 [mcve] 证明该问题(您可以用 Stack Snippets 做一个可运行的;here's how)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 2022-10-15
    • 1970-01-01
    • 2021-08-24
    • 2019-08-30
    • 2020-02-27
    • 2021-12-01
    相关资源
    最近更新 更多