【问题标题】:react.js get child value in parent componentreact.js 在父组件中获取子值
【发布时间】:2017-04-07 04:00:59
【问题描述】:

我有一个父组件 [MainLayout],它有一个子 [ListItems] 和多个子 [ListItem]。

如何获取[MainLayout]组件中被点击的子[ListItem]的值?

/* index.js */

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, Link, IndexRoute } from 'react-router'
import ListItems from './components/listitems';

class MainLayout extends Component {
    constructor(props) {
        super(props);

        this.state = {
            items: [],
            selectedItem: null
        };

        this.getTracks = this.getTracks.bind(this);

        this.listItemClicked = this.listItemClicked.bind(this);

        this.getTracks();

    }

    listItemClicked(item) {
        console.log(item);
    }

    getTracks() {

fetch('https://api.spotify.com/v1/search?q=newman&type=track&market=US')
                .then((response) => response.json())
                .then((responseJson) => {
                    this.setState({items: responseJson.tracks.items});
                    console.log(responseJson);
                    return responseJson;
                });
    }

    render() {
        return (
            <div>
                {this.props.children && React.cloneElement(this.props.children, {
                    items: this.state.items,
                    onListItemClicked: this.listItemClicked
                })}
            </div>
        );
    }
}

class App extends Component {
  constructor(props) {
    super(props);
  }

  render() {

    return (
        <div>
            <ListItems onListItemClick={this.props.onListItemClicked} items={this.props.items} />
        </div>
    );
  }

}


/* listitems.js */

import React, {Component} from 'react';
import ListItem from './listitem';

const ListItems = (props) => {

    const allitems = props.items.map((item) => {
        return (
            <ListItem onListItemClick={props.onListItemClick} item={item} key={item.id} />
        )
    });


        return (
            <ul className="list-group">
                {allitems}
            </ul>
        );


}
export default ListItems;

/* listitem.js */

import React, {Component} from 'react';

class ListItem extends Component {

    constructor (props) {
        super(props);
    }

    render() {
        return (
            <div className="">
                <h4 onClick={this.props.onListItemClick}>{this.props.item.album.artists['0'].name} - {this.props.item.name}</h4>
            </div>
        );
    }

}
export default ListItem;

感谢您的回答!

【问题讨论】:

    标签: javascript reactjs components


    【解决方案1】:

    您想要的解决方案可以在here找到。

    但我建议您使用任何单独的架构,例如 ReduxFlux。我知道您想要一个开销更少的答案,但请相信我,使用它会为您节省大量时间,并且他们可以有效地处理每个状态。我将谈论 Redux,因为我只在 Redux 工作过。


    Redux 如何解决你的问题?

    您需要的所有数据都存储在 Redux 存储中,可以从任何页面访问和更改。当您想要更改任何属性时,可以使用名为 dispatch() 的方法来帮助您这样做。为了访问 store 中的值,您可以使用 @connect() 装饰器。


    要了解有关调度程序的更多信息,请参阅link

    要了解@connect() 装饰器,请参阅此link

    Redux 和 Flux 的区别可以在 herehere 找到。

    【讨论】:

      【解决方案2】:

      在您的列表项中,您可以调用 onListItemClick 并将项目作为参数传递,例如 onClick={() =&gt; { this.props.onListItemClick(this.props.item); }}

      /* listitem.js */
      
      import React, {Component} from 'react';
      
      class ListItem extends Component {
      
          constructor (props) {
              super(props);
          }
      
          render() {
              return (
                  <div className="">
                      <h4 onClick={() => { this.props.onListItemClick(this.props.item); }}>{this.props.item.album.artists['0'].name} - {this.props.item.name}</h4>
                  </div>
              );
          }
      
      }
      export default ListItem;
      

      【讨论】:

      • 我之前试过这个,点击事件只在页面加载时到达 [MainLayout] 一次,因此它不适用于点击单个 ListItem
      • 您可能希望将 this.getTracks(); 生命周期移动到 componentDidMount 生命周期,因为您正在更改状态。不要在构造函数中这样做。可以参考https://facebook.github.io/react/docs/react-component.html#componentdidmount
      • 如果我 console.log 在 componentDidMount() 方法中的 this.state.items 我得到一个空数组.. 你能告诉我为什么吗?
      • 没错。您的州最初有一个空项目。只有在 getTracks() 从 spotify 成功获取项目后才会填充它。获取是异步的。 ComponentDidMount 调用 getTracks() 然后调用 fetch 并继续。它不会等待 fetch 完成。一旦 fetch 有结果,那么状态就会更新,并且它会再次触发重新渲染过程并使用更新的项目。希望这是有道理的。
      • 是的,我了解数据获取的工作方式,我想知道如何防止这种情况发生,即。等待渲染,直到有一些真实数据。此外,孙组件上的第一个 onClick 返回 null,第二个第三个等返回真实数据。这是为什么呢?
      猜你喜欢
      • 2018-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-31
      • 2016-07-19
      • 1970-01-01
      • 2019-11-27
      相关资源
      最近更新 更多