Javascript ReactJS-将数据从子组件传递到其父组件

Javascript ReactJS-将数据从子组件传递到其父组件,javascript,reactjs,jsx,Javascript,Reactjs,Jsx,我在应用程序中具有以下组件结构: class Car extends Component { constructor() { super(); this.state = { cars: [], ... } } componentDidMount() { axios.get('/api/cars') .then((response) =&g

我在应用程序中具有以下组件结构:

class Car extends Component {
    constructor() {
        super();
        this.state = {
            cars: [],
            ...
        }
    }
    componentDidMount() {
        axios.get('/api/cars')
            .then((response) => {
                this.setState({cars: response.data});
                console.log('cars: ', cars);
            }).catch(err => {
                console.log('CAUGHT IT! -> ', err);
            });
    }
    render() {
      return (
        ...
        <CarAddNew />
        <CarSearch />
        <CarList cars={this.state.cars} />
      )
    }
}

当我通过CarSearch组件在数据库中搜索数据时,它将获取并加载正确的数据,这很好。但是,如何将新发现的数据传递给CarList组件,以便在页面上显示?

我将执行以下操作:

class Car extends Component {
    constructor() {
        super();
        this.state = {
            cars: [],
            ...
        }
    }
    componentDidMount() {
        axios.get('/api/cars')
            .then((response) => {
                this.setState({cars: response.data});
                console.log('cars: ', cars);
            }).catch(err => {
                console.log('CAUGHT IT! -> ', err);
            });
    }
    handleSearch = () => {
        axios.post('/api/cars/search', searchCars)  // not sure where you are getting searchCars from, but you should get the idea
            .then(response => {
                this.setState({cars: response.data})
                console.log('response.data: ', response.data);
            })
    }

    render() {
      return (
        ...
        <CarAddNew />
        <CarSearch onSearch={this.handleSearch} />
        <CarList cars={this.state.cars} />
      )
    }
}


export default class CarSearch extends Component {
    constructor(){...}
    handleSearchSubmit(e) {
        e.preventDefault();
        this.props.onSearch() // I'm assuming you probably want to pass something here
    }
    render() {
        return(
          ... search form ...
        )
    }

我要做的是:

class Car extends Component {
    constructor() {
        super();
        this.state = {
            cars: [],
            ...
        }
    }
    componentDidMount() {
        axios.get('/api/cars')
            .then((response) => {
                this.setState({cars: response.data});
                console.log('cars: ', cars);
            }).catch(err => {
                console.log('CAUGHT IT! -> ', err);
            });
    }
    handleSearch = () => {
        axios.post('/api/cars/search', searchCars)  // not sure where you are getting searchCars from, but you should get the idea
            .then(response => {
                this.setState({cars: response.data})
                console.log('response.data: ', response.data);
            })
    }

    render() {
      return (
        ...
        <CarAddNew />
        <CarSearch onSearch={this.handleSearch} />
        <CarList cars={this.state.cars} />
      )
    }
}


export default class CarSearch extends Component {
    constructor(){...}
    handleSearchSubmit(e) {
        e.preventDefault();
        this.props.onSearch() // I'm assuming you probably want to pass something here
    }
    render() {
        return(
          ... search form ...
        )
    }

一种选择是通过一个道具上的CarSearch向上传播数据。考虑截断的例子…

handleSearchSubmit(e) {
  e.preventDefault();
  axios.post('/api/cars/search', searchCars).then(response => {
    this.props.onData(response.data);
  });
}
其中,onData将调用以下设置状态,然后在稍后设置状态

constructor() {
  // [...]
  this.onSearchResult = this.onSearchResult.bind(this);
}

onSearchResult(cars) {
  this.setState({cars}); // results from CarSearch
}

render() {
  return (
    <CarAddNew />
    <CarSearch 
      onData={this.onSearchResult} />
    <CarList 
      cars={this.state.cars} />
  )
}

一种选择是通过一个道具上的CarSearch向上传播数据。考虑截断的例子…

handleSearchSubmit(e) {
  e.preventDefault();
  axios.post('/api/cars/search', searchCars).then(response => {
    this.props.onData(response.data);
  });
}
其中,onData将调用以下设置状态,然后在稍后设置状态

constructor() {
  // [...]
  this.onSearchResult = this.onSearchResult.bind(this);
}

onSearchResult(cars) {
  this.setState({cars}); // results from CarSearch
}

render() {
  return (
    <CarAddNew />
    <CarSearch 
      onData={this.onSearchResult} />
    <CarList 
      cars={this.state.cars} />
  )
}

好吧,你可以从…传递数据。。。我会两次通过它吗?从Cars到CarList和CarSearch?不是,你有一个CarList组件,我想这是用来渲染一个汽车列表的,所以如果你有一个CarList来渲染汽车,你只需要将数据传递给CarList组件。当您在CarSearch组件中调用CarList组件时,请传递找到的日期。除了您的问题之外,不要尝试在更新后立即将您的状态记录下来。setState是异步的,因此使用这样的console.log是不健康的。setState有一个回调选项,但您可以随时轻松地在render方法中记录您的状态。。。我会两次通过它吗?从Cars到CarList和CarSearch?不是,你有一个CarList组件,我想这是用来渲染一个汽车列表的,所以如果你有一个CarList来渲染汽车,你只需要将数据传递给CarList组件。当您在CarSearch组件中调用CarList组件时,请传递找到的日期。除了您的问题之外,不要尝试在更新后立即将您的状态记录下来。setState是异步的,因此使用这样的console.log是不健康的。setState有一个回调选项,但您可以随时轻松地在render方法中记录您的状态。虽然我们的两个答案基本相同,但您的答案是在每次调用render时创建一个新函数,因为您在render中绑定。您至少应该在构造函数中绑定。虽然在构建过程中通过绑定来稍微提高性能是值得考虑的,但是您的答案不一样——您将子功能引入父组件。该问题询问如何将子组件函数结果发送到父组件,并将数据广播回相邻的同级组件。我将为微优化进行编辑。虽然我们的答案基本相同,但您的答案是在每次调用render时创建一个新函数,因为您是在render中绑定的。您至少应该在构造函数中绑定。虽然在构建过程中通过绑定来稍微提高性能是值得考虑的,但是您的答案不一样——您将子功能引入父组件。该问题询问如何将子组件函数结果发送到父组件,并将数据广播回相邻的同级组件。我将编辑微优化。我喜欢这种方法。更干净,更纯粹的孩子。谢谢你的答案-只是想知道-在搜索表单中,我想有按钮文本搜索时,搜索前或搜索后的数据和搜索。。。在搜索数据库的过程中。为此,我想向CarSearch组件添加一个状态变量,但我不知道当onSearch位于不同的组件中时如何检测此活动。非常感谢。您可以在Car组件中保留其状态,然后将其传递给CarSearch组件的道具。类似于:this.state={isSearching:false}然后在handleSearch:this.setState{isSearching:true}中获得搜索结果后,将其切换回false。我喜欢这种方法。更干净,更纯粹的孩子。谢谢你的答案-只是想知道-在搜索表单中,我想有按钮文本搜索时,搜索前或搜索后的数据和搜索。。。在搜索数据库的过程中。为此,我想向CarSearch组件添加一个状态变量,但我不知道当onSearch位于不同的组件中时如何检测此活动。非常感谢。您可以在Car组件中保留其状态,然后将其传递给CarSearch组件的道具。类似于:this.state={isSearching:false}然后在handleSearch:this.setState{isSearching:true}中获得搜索结果后,将其切换回false。