将道具传递给子组件

时间:2018-01-29 01:59:44

标签: javascript html reactjs constructor components

我似乎无法弄清楚如何将我的道具从我的App组件记录到我的子TotalBox组件。它一直作为空对象返回。有谁知道如何成功地做到这一点?

App.js

class App extends React.Component {
  constructor(props) {
    super(props);
    this.handler = this.handler.bind(this)
  }

  handler() {
    this.setState({
      value: 0
    })
  }

  render() {

  return (
  <Wrapper>
    <Grid>
      <Row>
        <CostBox/>
        <Input/>
        <TotalBox {...this.props}/>
      </Row>
    </Grid>
  </Wrapper>
)
  }
}

totalBox.js

class TotalBox extends React.Component {
  constructor(props) {
    super(props);
    console.log(this.props); // Object {}
    this.state = {
      value: this.props.value
    }
  }

  render() {
    return (
      <Col md={3}>
        <RightBox>
          <TotalCostHeader>TOTAL COST</TotalCostHeader>
          <TotalCostLabel>{this.state.value}</TotalCostLabel>
        </RightBox>
      </Col>
    )
  }
}

3 个答案:

答案 0 :(得分:1)

你真的打算通过this.props,还是打算通过this.state?从代码中,您似乎想要传递this.state,它具有value属性并使用传递的value属性。您还错过了this.state组件构造函数中App的初始化:

this.state = {
  value: 0,
}

另外,请记住,构造函数只有在组件首次渲染之前创建时才会被调用一次。以后更新传递的道具不会被constructor捕获。如果要捕获以后的更新,则必须使用componentWillReceiveProps(nextProps)组件生命周期方法。

如果您希望传递{...this.props}属性,我建议您不要使用value={this.props.value}语法,而应使用显式value{...this.props}似乎是一个干净的解决方案,但它的可读性较差,因为它没有提供您传递给组件的确切内容。这种语法很有用,但案例很少见。通常,它是一个通用的高阶组件,它包含另一个组件,并且您想要将道具传递给封闭的组件。

答案 1 :(得分:1)

@Jason,你需要从父母到孩子发送道具,如下所示:

 <TotalBox value={this.state.value}/>

答案 2 :(得分:1)

如前所述,你做错的第一件事就是在App组件中将value作为道具正确传递给TotalBox。您的this.state.value功能已完成handler()

乍一看,解决方案是简单地设置<TotalBox value={this.state.value}/>

但是现在我们遇到的问题是你的状态尚未设置,因为handler()函数尚未被调用(这是你根据代码实际设置状态的唯一地方)。

如果您希望稍后调用它,则需要在App组件中将某种占位符值设置为this.state.value。这看起来像这样:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.handler = this.handler.bind(this)
    this.state = {value: 0} // placeholder value set here
  }

  handler() {
    this.setState({
      value: 0
    })
  }

  render() {

  return (
  <Wrapper>
    <Grid>
      <Row>
        <CostBox/>
        <Input/>
        <TotalBox value={this.state.value}/>
      </Row>
    </Grid>
  </Wrapper>
)
  }
}

或者,如果尚未设置state或state.value,则可能无法呈现TotalBox组件。在App组件中是这样的:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.handler = this.handler.bind(this)
    this.state = {} // don't forget to declare the state object itself
  }

  handler() {
    this.setState({
      value: 0
    })
  }

    render() {
        const totalBox = this.state.value ? <TotalBox value={this.state.value}/> : null
          return (
          <Wrapper>
            <Grid>
              <Row>
                <CostBox/>
                <Input/>
                {totalBox}
              </Row>
            </Grid>
          </Wrapper>
        )
          }
}

编辑:您提到要通过子组件更新父级状态。这里是使用handler函数如何执行此操作的代码:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.handler = this.handler.bind(this)
  }

  handler() {
    this.setState({
      value: 0
    })
  }

  render() {

  return (
  <Wrapper>
    <Grid>
      <Row>
        <CostBox/>
        <Input/>
        <TotalBox value={this.state.value} handler={this.handler.bind(this)}/>
      </Row>
    </Grid>
  </Wrapper>
)
  }
}

class TotalBox extends React.Component {
  constructor(props) {
    super(props);
    console.log(this.props); // Object {}
    this.state = {
      value: this.props.value
    }
  }

 // Im using handler as a name for this function just as an example
 // this would be whatever you call as a function to update the state of
 // the parent component.
 handler () {
   // this is the function from your parent component
   // being executed to update its state
   this.props.handler()
 }  

  render() {
    return (
      <Col md={3}>
        <RightBox>
          <TotalCostHeader>TOTAL COST</TotalCostHeader>
          <TotalCostLabel>{this.state.value}</TotalCostLabel>
        </RightBox>
      </Col>
    )
  }
}