处理嵌套的React组件状态变化

5

所以,我有多个React组件。最初,我认为会有一个类似于父组件(我们称其为GrandPa)带有自己的状态,并且它将向另一个组件(称其为Parent)传递有关其状态的一些信息。同样,Parent将一些信息传递给Child,而Child则传递给GrandChild。因此,我们有以下层次结构:

GrandPa -> Parent -> Child -> GrandChild

然而,我很快意识到,当我使用this.setState(prevState => (<new state based on prevState>))方法更改GrandPa的状态时,更改不会沿着通道层级传递下去。我还意识到了向上传递变化的问题。我还没有找到一个好的方法来做到这一点。(之前,我通过将某些事件绑定到DOM中的组件,并具有可从所有React组件访问的公共变量来执行一些超级不稳定的操作。然后,当任何人触发特定事件时,我会尝试触发更新各自组件的事件......长话短说,这创建了很多问题,并且很丑陋。)

因此,我有下面的示例代码,其中我尝试仅使用父组件和子组件来实现这一点。这是一个虚拟示例,但它只是为了学习如何做到这一点。名为ReactRandom的父组件具有状态{name: <name>},并且具有将该名称更改为随机字符串的方法。当ReactRandom渲染时,它会从另一个组件ReactRandomNested中渲染该名称,后者基本上通过自己的props打印出传递的名称。在这里,我创建了一个方法,位于ReactRandomNested内部,用于明确呈现更改(顺便说一句,我不想这样做,我认为有一种方法可以在不必要显式执行此操作的情况下沿着通道级联更新,因为随着嵌套级别的增加,将很快变得笨重)。但是,即使这也不起作用。它会有1步延迟,并在当前时间步骤中呈现先前的更新。

总之,以下是我目前拥有的代码:

class RandomReactNested extends React.Component {
    constructor(props) {
        super(props);
        this.state = {name: props.name};
    }

    handleChange() {
        let self = this;
        self.setState({name: self.props.name});
    }

    render() {
        let self = this;
        return React.createElement("span", {
            onClick: () => self.handleChange.call(this)
        }, self.state.name);
    }
}

class RandomReact extends React.Component {
    constructor (props){
        super(props);
        this.state = {name: props.name};
        this.changeName.bind(this);
    }

    changeName () {
        let random_word_length = Math.round(Math.random()*20),
            index_count = 0,
            new_name = "",
            alphabet = "abcdefghijklmnopqrstuvwxyz";
        for (index_count; index_count <= random_word_length; index_count += 1) {
            new_name += `${alphabet[Math.round(Math.random()*random_word_length)]}`;
        }
        console.log(new_name);

        this.setState(prevState => ({
            name: new_name
        }));
    }

    render() {
        let self = this;
        return React.createElement("div", {
            key: 2,
            onClick: () => (this.changeName.call(self))
        },
            React.createElement(RandomReactNested, {
                name: self.state.name
            }));
    }
}

顺便说一下,我对React还很陌生,正在努力学习如何有效地使用它。我也从ReactJS网站的页面末尾(https://reactjs.org/docs/composition-vs-inheritance.html)看到了这个,似乎建议不要使用继承(但我不是完全确定?): "那么继承呢? 在Facebook,我们在成千上万的组件中使用React,我们没有发现任何使用情况需要创建组件继承层次结构。 Props和组合为您提供了所有所需的灵活性,以显式且安全的方式自定义组件的外观和行为。请记住,组件可以接受任意props,包括原始值、React元素或函数。 如果您想在组件之间重用非UI功能,我们建议将其提取到单独的JavaScript模块中。组件可以导入并使用该函数、对象或类,而无需扩展它。"

1
以下是我找到的答案:x) https://stackoverflow.com/questions/46727804/update-a-react-components-state-from-its-parent - Robert Vunabandi
1个回答

7

咳嗽,redux,咳嗽

顺便提一句,传递props是单向的!你可以将东西传递下去并使用它们,但你不能将它们传递回来。唯一操作父组件的方式就是通过将整个函数作为props进行传递。

updateGrandpaState(newData){
this.setState({ originalData: newData})
}

从您的爷爷组件中,您可以像这样向下传递它...

<ParentComponent updateGrandpaState={this.updateGrandpaState} />

在您的父组件中,您可以调用以下内容:
this.props.updateGrandpaState(parentComponentData)

这将触发位于grandpaComponent中的原始函数,从而更新grandpaComponent状态。

是的,您可以进一步深入,但请注意,越深入,代码会变得越复杂...

在Grandpa组件内部

< ParentComponent updateGrandpaState={this.updateGrandpaState} /> 

父级元素内部

< ChildComponent updateGrandpaState={this.props.updateGrandpaState} />

内部子元素

this.props.updateGrandpaState(childComponentData)

当你深入两个级别时,在进行开发工作时我也会在componentDidMount中使用console.log(this.props)。

更酷的是,你甚至可以将grandpaState传递给ParentComponent以供使用,并将其连接到componentWillRecieveProps......

<ParentComponent grandpaState={this.state} updateGrandpaState={this.updateGrandpaState} />

但是说实话,一旦你学会了Redux,并设置了几次,它真的很棒,我再也不会不使用它了!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接