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

IT技术 javascript reactjs inheritance multiple-inheritance
2021-05-15 17:31:50

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

爷爷 -> 父级 -> 子级 -> GrandChild

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

所以,我有下面的示例代码,我试图只用父母和孩子来做到这一点。这是一个虚拟的例子,但它只是为了学习如何做到这一点。被调用的父对象ReactRandom有一个状态,{name: <name>}并且有一个方法可以将该名称更改为随机字符串。ReactRandom渲染,它使得从另一个组件,它的名字ReactRandomNested基本上打印出通过自己的props通过了名。在这里,我创建了一个在ReactRandomNested其中显式呈现更改的方法(我不想要顺便说一句,我认为有一种方法可以将更新级联到通道中而不必明确地这样做,因为它会变得令人讨厌,因为我们有 >2 个嵌套级别)。但是,即使这样也行不通。它有 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 module中。组件可以导入它并使用该函数、对象或类,而无需扩展它。”

1个回答

咳嗽,还原,咳嗽

反正路过props是一条单行道!你可以传递东西,使用它们,但你不能传递它们。操作父组件的唯一方法是将整个函数作为 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,设置几次,它真的很棒,我永远不会使用它!