反应-通过回调更改child1的道具并将新值传递给child2

时间:2019-09-03 19:35:18

标签: javascript reactjs

在我的应用中,我有一个子组件“菜单”,其中的点击事件会更新“选择”状态,例如:

Menus.jsx (子级):

import React, { Component } from 'react';
import { Redirect } from 'react-router-dom';
import Brewing from './Brewing.jsx';
import { withRouter } from 'react-router-dom';


class Menus extends Component{
  constructor (props) {
    super(props);
    this.state = { 
        select: '',      
        isLoading: false,
        redirect: false
    };
  };

  (...)

  gotoCoffee = (index) => {
    this.setState({isLoading:true, select:this.state.coffees[index]})
    setTimeout(()=>{
      this.setState({isLoading:false,redirect:true})
    },5000)
    console.log(this.state.coffees[index])
  }

  renderCoffee = () => {
    if (this.state.redirect) {
      return (<Redirect to={'/coffee/'+this.state.select} />)
    }
  }

  render(){
    const coffees = this.state.coffees;

    return (
      <div>
        <h1 className="title is-1"><font color="#C86428">Menu</font></h1>
        <hr/><br/>
        {coffees.map((coffee, index) => 
          <span key={coffee}>
            <div>
               {this.state.isLoading && <Brewing/>}
               {this.renderCoffee()}
              <div onClick={() => this.gotoCoffee(index)} 
                   style={{textDecoration:'underline',cursor:'pointer'}}>
                  <strong><font color="#C86428">{coffee}</font></strong></div>
              <div>
              </div>
            </div>
          </span>)
        }
      </div>
    );
  }
}

export default withRouter(Menus);

以上作品。


但是,假设我有另一个子组件“ Coffee”,它应该继承此更改后的状态。

我了解到,将此事件更改和状态(从子项传递到另一个子项)是一种反模式。考虑到React的方式,数据只能从上到下,即从父级到子级流动。

所以我尝试从上到下管理“选择”状态,就像这样:

App.jsx (父级)

class App extends Component {
  constructor() {
    super();
    this.state = {
      select: '',
    };
    this.onSelectChange = this.onSelectChange.bind(this);
  };

然后我将在'App.jsx'处使用回调,如下所示:

onSelectChange(newSelect){ 
    this.setState({ select: newSelect });
  }

并将其传递给“菜单”组件,如下所示:

<Route exact path='/menus' render={() => (
                    <Menus
                      onSelectChange={this.onSelectChange}
                    />
                  )} />

最后,在子菜单“ Menus”中,我将用户更改事件以更改道具,并可以将其传递给其他子项,例如:

gotoCoffee = (index) => {
    this.setState({isLoading:true})
    this.props.onSelectChange(index)
    setTimeout(()=>{
      this.setState({isLoading:false,redirect:true})
    },5000)
    console.log(this.props.select)
  }

但是我得到console.log(this.props.select)'未定义'。

我想念什么?

1 个答案:

答案 0 :(得分:0)

您现在仅将onSelectChange方法作为道具传递给Menu组件,要访问this.props.select,您需要将select作为道具传递给Menu。

<Route exact path='/menus' render={() => (
  <Menus
    onSelectChange={this.onSelectChange}
    select={this.state.select}
  />
)} />

无论何时调用this.onSelectChange方法并在App.jsx中更改状态,都会呈现Menu组件。您可以在渲染方法或菜单组件的任何非静态方法中使用更新的 this.props.select

class Menu extends Component {

  render() {
    console.log(this.props.select);

    return (
      ...
    );

  }
}