首页 > 解决方案 > 如何将孙子数据传递给 GrandParent 组件而不将数据传递给 Reactjs 中的中间组件?

问题描述

我已经创建了三个组件 Aboutus、AboutusChild 和 GrandChild,现在我想在我的祖父组件中传递孙子状态值,即“Aboutus”组件但不使用中间组件(AboutusChild),是否可以在不使用 redux 状态管理库的情况下反应 js .

在某些数据通信概念不清楚之前,我现在不想使用 redux。

class AboutUs extends Component {
            constructor(props) {
                super(props)`enter code here`
                this.state = {
                    childState: false
                }
            }
            myMehtod(value) {
                this.setState({
                    childState: value
                })
            }
            render() {
                console.log('AboutUs', this.state.childState)
                return (
                    <div>
                        <h1 className={`title ${this.state.childState ? 'on' : ''}`}>
                            About us {this.props.aboutusProp}
                        </h1>               
                        <AboutUsChild />
                    </div>
                )
            }
        };
    class AboutUsChild extends Component {
    myMehtod(value) {
        this.setState({
            childState: value
        },
            this.props.myMehtodProp(!this.state.childState)
        )

    }
    render() {
        console.log('AboutUsChild', this.state.childState)
        return (
            <div>
                <h1 className={`title ${this.state.childState ? 'on' : ''}`}>About Us Child</h1>
                <GrandChild>
                    without function
                </GrandChild>
                <h1>About Us Child</h1>
                <GrandChild Method={true} myMehtodProp={this.myMehtod.bind(this)} />
            </div>
        )
    }
};
    class GrandChild extends Component {
        constructor() {
            super()
            this.state = {
                TitleClick: false
            }
        }
        TitleClick() {
            this.setState(
                {
                    TitleClick: !this.state.TitleClick
                },
                this.props.myMehtodProp(!this.state.TitleClick)
            )

        }
        render() {
            console.log('GrandChild', this.state.TitleClick)
            return (
                <div>
                    {this.props.Method ?
                        <h1 onClick={this.TitleClick.bind(this)} className={`title ${this.state.TitleClick ? 'on' : ''}`}>Grand Child</h1>
                        : null}
                    <h1>{this.props.children}</h1>
                </div>
            )
        }
    };

标签: reactjs

解决方案


如果不将子状态传递给某个回调,真的没有办法传递子状态。但坦率地说,这对我来说似乎不是一个好的设计选择。您应该始终在使用该状态的所有组件之上拥有公共状态。您可以做的是将东西作为孩子传递:

class SomeComponent extends React.Component {
  ...
  render() {
    const { value } = this.state;

    return (
      <Child value={value}>
        <GrandChild value={value} onChange={this.handleValueChange} />
      </Child>
    );
  }
}

const Child = ({ value, children }) => (
  <div>
    <h1 className={`title ${value ? 'on' : ''}`}>About Us Child</h1>
    {children}
  </div>
)

const GrandChild = ({ value, onChange }) => (
  <div>
    <h1 onClick={onChange} className={`title ${value ? 'on' : ''}`}>Grand Child</h1>
  </div>
);

这样,您就可以从所有内容的父组件中获得控制权。如果这不是方式,因为你已经传递了孩子,并且由于某种原因你想保持这种方式,你可以传递“渲染”道具:

// JSX in <SomeComponent /> render function:
<Child
  value={value}
  grandChild=(<GrandChild value={value} onChange={this.handleValueChange} />)
>
  Some other children
</Child>

...

const Child = ({ value, grandChild, children }) => (
  <div>
    <h1 className={`title ${value ? 'on' : ''}`}>About Us Child</h1>
    {grandChild}
    {children}
  </div>
)

如果你想更花哨并且嵌套层次多,你总是可以使用上下文(强烈建议在使用前阅读文档):

const someContext = React.createContext({ value: true, onChange: () => {} });

class SomeComponent extends React.Component {
  ...
  render() {
    const { value } = this.state;
    return (
      <someContext.Provider value={{ value: value, onChange: this.handleValueChange }}>
        <Children>
      </someContext.Provider>
    );
  }
}

...

const SomeDeeplyNestedChildren = () => (
  <someContext.Consumer>
    {({ value, onChange }) => (
      <h1 onClick={onChange}>{value}</h1>
    )}
  </someContext.Consumer>
)

如果您的结构不是那么复杂,我会选择前两个,但是如果您要深入传递道具,请使用上下文。


推荐阅读