React.js组件子项 - 全局交互

时间:2018-02-21 21:14:00

标签: javascript reactjs

React.js中的组件子项

我正在创建一个可以被视为加密投资组合列表的应用程序。每个硬币项目都有一些细节,如持有和价格。它们保存在localstorage中保存的字典中,并加载到组合容器组件中。州。

层次结构可以看作是Container> PortfolioList>项目组合。

我的问题如下:点击投资组合项目,我想用一个名为PortfolioDetails的投资组合硬币(显示历史图表)的API调用来填充一个完全不同的组件。

问题

如何在React.js中最好地处理此组件 - 全局交互?最好的做法是在PortfolioContainer中定义一个状态并在点击PortfolioItem子项时将其更改(通过2个父项传递),或者有没有办法在onClick上重新呈现PortfolioDetails组件,就像我在这里试过的那样?

谢谢!

export default class PortfolioContainer extends React.Component{
constructor(props){
    super(props);
    this.state = (
        {portfolio:
          {ICX:{transactions:[{purchase: '$49.99', amount: 50}], price:{raw:{BTC:{PRICE:3.20}}, display:{BTC:{PRICE:3.20}}}},
        currency: 'BTC',
        total: 0
        }
    )
}

render(){

    return(
        <Container>
            <Row>
                <Col xs="12">
                    <PortfolioList currency={this.state.currency} portfolio={this.state.portfolio} />
                    <PortfolioDetails show='portfolio'/>
                </Col>
            </Row>
        </Container>
    );
}
}    


export class PortfolioList extends React.Component{
constructor(props){
    super(props);
}



render(){
    const rows = [];

    if(Object.keys(this.props.portfolio).length > 0){
        Object.keys(this.props.portfolio).map((coin, details) =>{

            rows.push(
                <CoinRow
                coin={coin}
                details={this.props.portfolio[coin]}
                currency={this.props.currency}
                key={coin}
                />
            )
        });
    }
    return(
        <table>
            <thead>
                <tr>
                    <th>Coin</th>
                    <th>Holdings</th>
                    <th>Price</th>
                </tr>
            </thead>
            <tbody>
            {rows}
            </tbody>
        </table>
    );
}
}

export class CoinRow extends React.Component{
constructor(props){
    super(props)
    this.handleClick = this.handleClick.bind(this);
}

handleClick(e){
    e.preventDefault();
    // Get coin ID from clicked event
    var coinId = e.currentTarget.attributes['data-id'].value;
    // Populate portfolio details with coin details
    <PortfolioDetails show={coinId}/>

}

render(){
    const coin = this.props.coin;
    const details = this.props.details;
    var holdings = null;
    return (
        <tr data-id={coin} onClick={this.handleClick}>
            <td>{coin}</td>
            <td>{holdings}</td>
            <td>{details.price.display[this.props.currency].PRICE}</td>
        </tr>
    );
}
} 
export class PortfolioDetails extends React.Component{
constructor(props){
    super(props);
}


render(){
    var showing = this.props.show;
    return(
        <div>
            // Showing details for the following coin
            <p>{showing}</p>
        </div>
        );
}
}

2 个答案:

答案 0 :(得分:1)

是的,最佳做法是让PortfolioContainer管理隐藏/显示儿童的状态。这将是让整个组件树更新的最简单方法。你可以在那里使用handlePortfolioItemClick方法,可以更新状态以显示PortfolioDetails内的不同数据。

答案 1 :(得分:1)

执行所需操作的最佳方法是使用Redux

这样你会有这样的流程:

redux flow

您是否看到UI定义了State,并且有一个包含应用Store的唯一State?这就是Redux在您的用例中运行良好的原因。

您可以在State中保留Store,如:

cryptoPorfolio: { // this is the name of the reducer, it will be part of the state tree, read below
  coin: ''
}

现在,您可以更新此State在&#39;用户界面中触发操作,该操作将发送到最终进行更新的Reducer。像这样:

<强>动作

{
  type: 'UPDATE_COIN',
  coinName: 'ETH'
}

动作创建者(只是可以由UI触发的功能)

function updateCoin(coin) {
    return {
      type: 'UPDATE_COIN',
      coinName: 'Ethereum'
    }
}

您可以使用react-redux中的bindActionCreators将您的操作创建者传递给您的组件。

然后,在您的Component中,您可以将此动作创建者称为传递为prop的普通函数,以便将操作发送到reducer。

最后,在reducer中,您可以更新Store。例如:

function cryptoPorfolio(state = initialState, action) {
  switch (action.type) {
    case UPDATE_COIN:
      return Object.assign({}, state, {
        coin: action.coinName
      })
    default:
      return state
  }
}

有关详细信息,请阅读Redux usage with React