如何在不将数据传递到Reactjs中的中间组件的情况下将孙子数据传递到GrandParent组件?

时间:2019-01-19 09:20:28

标签: reactjs

我已经创建了三个组件Aboutus,AboutusChild和GrandChild,现在我想在我的祖父母组件(即Aboutus组件)中传递孙子状态值,但不使用中间组件(AboutusChild),是否可以在React js中不使用redux状态管理库。

在某些数据通信概念不清楚之前,我现在不想使用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>
            )
        }
    };

2 个答案:

答案 0 :(得分:0)

在没有将子状态传递给某些回调的情况下,实际上是没有办法的。但是坦率地说,在我看来,这似乎不是一个好的设计选择。在使用该状态的所有组件之上,您应该始终具有公共状态。您所能做的就是让孩子们通过东西:

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>
);

这样,您就可以从所有内容的父级组件获得控制权。如果不是这样,因为您已经通过了子代,并且出于某种原因想要保持这种方式,则可以通过“ render”道具:

// 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>
)

如果您想更加精美,并且嵌套层次不止几个,可以随时使用context(强烈建议在使用前阅读文档):

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>
)

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

答案 1 :(得分:0)

在没有外部库的情况下进行此类操作的唯一方法是利用React's Context API,尽管要记住,它不如redux或mobX强大。