处理嵌套的React组件的状态更改

时间:2017-12-17 18:34:29

标签: javascript reactjs inheritance multiple-inheritance

所以,我有多个ReactComponent。最初,我认为有一个父组件(让我们称之为GrandPa)有自己的状态,它会将有关其状态的一些信息传递给另一个组件(称之为Parent)。同样,父母将他的一些孩子和孩子传给了GrandChild。所以我们有层次结构:

GrandPa - >家长 - >孩子 - >如GrandChild

然而,我很快意识到,当我使用方法this.setState(prevState => (<new state based on prevState>))更改GrandPa的状态时,更改不会使通道级联。我意识到的另一个问题是在频道上传递更改。我还没有找到一个很好的方法来做到这一点。 (之前,我通过将一些事件绑定到DOM中的组件并具有可从所有ReactComponent访问的公共变量来做一些超级粗略的事情。然后当任何人触发特定事件时,我会尝试触发将更新事件的事件各个组成部分......长话短说,这造成了很多问题并且很难看。)

所以,我有下面的示例代码,我尝试只使用父和子这样做。这是一个虚拟的例子,但它只是学习如何做到这一点。名为ReactRandom的父级具有状态{name: <name>},并且具有将该名称更改为随机字符串的方法。当ReactRandom呈现时,它会从另一个组件ReactRandomNested呈现该名称,该组件基本上打印出通过其自己的道具传递的名称。在这里,我在ReactRandomNested内部创建了一个方法,它明确地呈现了这些更改(我不想要这样做,我认为有一种方法可以将更新级联到通道而不必明确地执行此操作,因为它是因为我们有> 2个嵌套级别而变得讨厌。但是,即使这样也行不通。它有一步延迟,并在当前时间步长呈现先前的更新。

无论如何,这是我目前的代码:

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,并且我们没有找到任何建议创建组件继承层次结构的用例。 道具和组合为您提供了以明确和安全的方式自定义组件外观和行为所需的所有灵活性。请记住,组件可以接受任意道具,包括原始值,React元素或函数。 如果要在组件之间重用非UI功能,我们建议将其提取到单独的JavaScript模块中。组件可以导入它并使用该函数,对象或类,而无需扩展它。“

1 个答案:

答案 0 :(得分:5)

咳嗽,减量,咳嗽

无论如何,路过道具是一条单行道!你可以将事情传递下去并使用它们,但是你无法传递它们。操纵父组件的唯一方法是将整个函数作为props传递。

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

从爷爷组件中你可以将它传递给你......

<ParentComponent updateGrandpaState={this.updateGrandpaState} />

在您的父组件中,您可以调用

this.props.updateGrandpaState(parentComponentData)

然后将触发生成在grandpaComponent中的原始函数,从而更新grandpaComponent状态。

是的,你可以更进一步,预警,你越往前走得越深......

爷爷里面

< 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,设置了几次,它真的很棒,我永远不会用它!