【问题标题】:how to pass props to a component via onClick event?如何通过 onClick 事件将道具传递给组件?
【发布时间】:2017-10-19 23:22:04
【问题描述】:

我在这里遍历列表并显示可点击的{expense.createdAt}。当我点击{expense.createdAt} 时,我想在同一页面上显示它的<ExpenseDetails />,所以我需要传递道具。如何使用 onClick 做到这一点?

我下面的代码不显示任何内容。

class ExpenseList extends Component {

  render () {
    const {expenses} = this.props;
    const list = expenses.expenseList.map(expense =>
        <Segment clearing key={expense.uid} >
          <a href="" onClick={() => {this.passProps(expense)}}>
            {expense.createdAt}
          </a>
        </Segment>
    )

    const details = function passProps(expense){
      return (
        <div>
          <ExpenseDetails expense={expense}/>
        </div>
      )
    }

    return (
        <div>
          <Grid celled='internally'>
            <Grid.Row>
              <Grid.Column width={5}>
                <div>
                  <h1>Your Expense List:</h1>
                  <Segment.Group raised>

                    {list}

                  </Segment.Group>
                </div>

              </Grid.Column>
              <Grid.Column width={11}>
                <Segment>

                  {details}

                </Segment>
              </Grid.Column>
            </Grid.Row>
          </Grid>
        </div>

    )
  }
}

当我点击{expense.createdAt} 时,页面会刷新。这可能是个问题。我怎样才能防止这种情况发生?

console.log(this.props.expenses):

【问题讨论】:

  • 什么是this.passProps?请展示您的整个组件。
  • 我编的。它应该是一个将 props 传递给 &lt;ExpenseDetails /&gt; 并在屏幕上呈现 &lt;ExpenseDetails /&gt; 组件的操作。我将此操作存储在const details 中。那有意义吗?我对此很陌生。
  • 代码中的每一个元素都是示例吗?你真的有一个Segment 具有你想要的功能的组件吗?您愿意改变当前组件层次结构的方式吗?
  • 是的,如果我输入 &lt;ExpenseDetails /&gt; 而不是 {details} 我会从该组件中获取示例文本。所以它似乎工作正常。 &lt;Segment&gt; 和其他只是语义 UI 样式的组件。

标签: reactjs


【解决方案1】:

这样的事情应该可以工作。重要的概念是您需要有一个父组件来传递数据的两个子组件。在这种情况下,Expenses 是父级。在父级中,您创建一个函数showItemDetails,并将其传递给ExpenseList。那是您的 clickhandler,它用于传递您要呈现的数据的索引位置。然后showItemDetails 使用this.setStateItemDetails 提供你想要的道具。

import React, {Component} from 'react'

export default class Expenses extends Component {
  constructor(props) {
    super(props)
    this.state = {
      expenseItems: []
    }
  }

  showItemDetails(idx) {
    const {expenseItems} = this.props.expenses.expenseList[idx]
    this.setState({expenseItems})
  }

  render() {
    const createdDates = this.props.expenses.expenseList.map(({createdAt}) => {
      return createdAt
    })
    const expenseListProps = {
      showItemDetails: (idx) => this.showItemDetails(idx),
      createdDates
    }
    const itemDetailsProps = {expenseItems: this.state.expenseItems}
    return (
      <div>
        <ExpenseList {...expenseListProps}/>
        <ItemDetails {...itemDetailsProps}/>
      </div>
    )
  }
}

class ExpenseList extends Component{
  render() {
    const expenseList = this.props.createdDates.map((date, idx) => (
      <div key={idx}>
        <button onClick={() => this.props.showItemDetails(idx)}>
          {date}
        </button>
      </div>
    ))
    return (
      <div>
        {expenseList}
      </div>
    )
  }
}

class ItemDetails extends Component {
  render() {
    debugger;
    const items = this.props.expenseItems.map(({uid, date, desc, amount}) => (
      <div>
        {uid}
        {date}
        {desc}
        {amount}
      </div>
    ))
    return (
      <div>
        {items}
      </div>
    )
  }
}

【讨论】:

  • 谢谢。我有点理解你的建议,但有点困惑。你把{list}放在哪里? &lt;Expense /&gt; 是指&lt;ExpenseDetails /&gt;?为了澄清我的观点(最终结果),请查看我之前的帖子。这是一张概念图:stackoverflow.com/questions/46821789/…
  • @karolis2017 啊,我明白了。我刚刚向您展示的内容不适用于这种渲染风格。如果你是 React 的新手,那么实现它可能看起来很混乱。我可以告诉你如何在没有 Redux 的情况下做到这一点,但 Redux 是更合乎逻辑的方法。
  • 期待看到没有Redux的代码。这是一个相当简单的应用程序,所以不想增加任何复杂性。
  • @karolis2017 请给我看看this.props.expense 的样张
  • 你的意思是我传递给&lt;ExpenseList /&gt;的状态?
猜你喜欢
  • 1970-01-01
  • 2018-01-07
  • 2018-04-15
  • 1970-01-01
  • 1970-01-01
  • 2020-04-03
  • 2020-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多