最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Pass state to a component in another file in react - Stack Overflow

programmeradmin1浏览0评论

I have an App ponent with a few ponents in it for example menu, sidebar, repos etc. In the menu ponent there is a search bar. When you submit whatever you typed in the search bar it does a request to /. Then I change the json to user state. But how do I pass the data to repos ponent? Is this possible?

App.js

import React, { Component } from 'react';
import Sidebar from './layout/Sidebar';
import Menu from './layout/Menu';
import Repos from './githubdata/Repos';
import Followers from "./githubdata/Followers";
import Following from "./githubdata/Following";
import BirthCount from "./githubdata/BirthCount";

class App extends Component{
    render(){
        return(
            <div className="wrapper">
                <Sidebar />
                <div className="main-panel">
                    {* In this ponent the magic happens *}
                    <Menu />
                    <div className="content">
                        <div className="container-fluid">
                            <div className="row">
                                {* I want to display the data in this ponent *}
                                <Repos />
                                <Followers />
                                <Following />
                                <BirthCount />
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}

export default App;

Menu.js

import React, { Component } from 'react';

class Menu extends Component {
    constructor(props){
        super(props);
        this.state = {
            query: ''
        }
    }

    handleChange = (event) => {
        this.setState({
            query: event.target.value
        })
    };

    search = () => {
        const BASE_URL = '/';
        let FETCH_URL = `${BASE_URL}${this.state.query}`;
        console.log('fetchurl', FETCH_URL)

        fetch(FETCH_URL, {
            method: 'GET'
        })
            .then(response => response.json())
            .then(json => {
                const user = json;
                console.log('user json', user);
                this.setState({
                    user
                })
            });
    };

    render(){
        return(
            <div>
                <input onChange={this.handleChange} value=this.state.query} type="text"/>
                <button onClick={this.search}>submit</button>
            </div>
        )
    }
}
export default Menu;

I have an App ponent with a few ponents in it for example menu, sidebar, repos etc. In the menu ponent there is a search bar. When you submit whatever you typed in the search bar it does a request to https://api.github./users/. Then I change the json to user state. But how do I pass the data to repos ponent? Is this possible?

App.js

import React, { Component } from 'react';
import Sidebar from './layout/Sidebar';
import Menu from './layout/Menu';
import Repos from './githubdata/Repos';
import Followers from "./githubdata/Followers";
import Following from "./githubdata/Following";
import BirthCount from "./githubdata/BirthCount";

class App extends Component{
    render(){
        return(
            <div className="wrapper">
                <Sidebar />
                <div className="main-panel">
                    {* In this ponent the magic happens *}
                    <Menu />
                    <div className="content">
                        <div className="container-fluid">
                            <div className="row">
                                {* I want to display the data in this ponent *}
                                <Repos />
                                <Followers />
                                <Following />
                                <BirthCount />
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}

export default App;

Menu.js

import React, { Component } from 'react';

class Menu extends Component {
    constructor(props){
        super(props);
        this.state = {
            query: ''
        }
    }

    handleChange = (event) => {
        this.setState({
            query: event.target.value
        })
    };

    search = () => {
        const BASE_URL = 'https://api.github./users/';
        let FETCH_URL = `${BASE_URL}${this.state.query}`;
        console.log('fetchurl', FETCH_URL)

        fetch(FETCH_URL, {
            method: 'GET'
        })
            .then(response => response.json())
            .then(json => {
                const user = json;
                console.log('user json', user);
                this.setState({
                    user
                })
            });
    };

    render(){
        return(
            <div>
                <input onChange={this.handleChange} value=this.state.query} type="text"/>
                <button onClick={this.search}>submit</button>
            </div>
        )
    }
}
export default Menu;
Share Improve this question asked Oct 26, 2017 at 9:05 twoamtwoam 8925 gold badges14 silver badges31 bronze badges 1
  • are you using redux or flux? there is a simple solution then, if no i will try to post mine – hannad rehman Commented Oct 26, 2017 at 9:11
Add a ment  | 

5 Answers 5

Reset to default 2

Move your search function to parent ponent App.

In Repo you can get by users by this.props.user

App.js

import React, { Component } from "react";
import Sidebar from "./layout/Sidebar";
import Menu from "./layout/Menu";
import Repos from "./githubdata/Repos";
import Followers from "./githubdata/Followers";
import Following from "./githubdata/Following";
import BirthCount from "./githubdata/BirthCount";

class App extends Component {
  constructor() {
    super();
    this.state = { user };
  }
  search = (query) => {
    const BASE_URL = "https://api.github./users/";
    let FETCH_URL = `${BASE_URL}${query}`;
    console.log("fetchurl", FETCH_URL);

    fetch(FETCH_URL, {
      method: "GET"
    })
      .then(response => response.json())
      .then(json => {
        const user = json;
        console.log("user json", user);
        this.setState({
          user
        });
      });
  };

  render() {
    return (
      <div className="wrapper">
        <Sidebar />
        <div className="main-panel">
          {/* In this ponent the magic happens */}
          <Menu search={this.search.bind(this)} />
          <div className="content">
            <div className="container-fluid">
              <div className="row">
                {/* I want to display the data in this ponent */}
                <Repos user={this.state.user} />
                <Followers />
                <Following />
                <BirthCount />
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

export default App;

Yes this is possible. You'll have to use something called props https://facebook.github.io/react-native/docs/props.html

// APP.JS
.....
<div className="row">
   {* I want to display the data in this ponent *}
        <Repos data={dataToBePassed} />
        <Followers />
        <Following />
        <BirthCount />
   </div>
.....


// REPOS.JS
...
render(){
     return (<div>{this.props.datatobepassed}</div>)
}
....

here is what you need to do if you are not using redux/flux.

class App extends Component{
constructor(props){
   super(props);
     this.state={results:[]};
  this.dataFromSearch=this.dataFromSearch.bind(this);
}
dataFromSearch(data){
this.setState({results:data});
}
render(){
    return(
        <div className="wrapper">
            <Sidebar />
            <div className="main-panel">
                {* In this ponent the magic happens *}
                {* dataFromSearch will be called when you actually have data 
                   you can pass the same props into the next child of Menu 
                *}
                <Menu callbackFn={this.dataFromSearch} />
                <div className="content">
                    <div className="container-fluid">
                        <div className="row">
                            {* I want to display the data in this ponent *}
                            <Repos searchData={this.state.results} />
                            <Followers />
                            <Following />
                            <BirthCount />
                        </div>
                    </div>
                </div>
            </div>
        </div>
    )
}

}

Call the props method in MENU when you have the data

class Menu extends Component {
constructor(props){
    super(props);
    this.state = {
    }
}

search = () => {
    const BASE_URL = 'https://api.github./users/';
    let FETCH_URL = `${BASE_URL}${this.state.query}`;
    console.log('fetchurl', FETCH_URL)

    fetch(FETCH_URL, {
        method: 'GET'
    })
        .then(response => response.json())
        .then(json => {
            const user = json;
            console.log('user json', user);
            this.setState({
                user
            })  
            // this will call the fn in App and your app state will be 
            //updated
            this.props.callbackFn(user);
        });
}; 

render(){
    return(
        <div>
            {// providing `onChange` callback and `query` value from props}
            <input onChange={this.props.onChange} value={this.props.query} type="text"/>
            <button onClick={this.search}>submit</button>
        </div>
    )
}

}

so after all execution your App state will have the data , that is passed to Repo ponent as Props. you can access it there easily/

You will need to lift that state up from the Menu ponent, to the "owning" App ponent, then pass it down to Repos, Followers, etc.

You could achieve this by moving a state in App ponent:

class App extends Component{
    constructor(props){
        super(props);
        this.state = {
            query: ''
        }
    }

    handleChange = (event) => {
        this.setState({
            query: event.target.value
        })
    }

    render(){
        return(
            <div className="wrapper">
                <Sidebar />
                <div className="main-panel">
                    {* Provide the query value to Menu ponent *}
                    <Menu onChange={this.handleChange} query={this.state.query} />
                    <div className="content">
                        <div className="container-fluid">
                            <div className="row">
                                {* And provide the same data to Repos ponent *}
                                <Repos query={this.state.query} />
                                <Followers />
                                <Following />
                                <BirthCount />
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}

Next, you can remove state handling from Menu ponent:

class Menu extends Component {
    constructor(props){
        super(props);
        this.state = {
        }
    }

    search = () => {
        const BASE_URL = 'https://api.github./users/';
        let FETCH_URL = `${BASE_URL}${this.state.query}`;
        console.log('fetchurl', FETCH_URL)

        fetch(FETCH_URL, {
            method: 'GET'
        })
            .then(response => response.json())
            .then(json => {
                const user = json;
                console.log('user json', user);
                this.setState({
                    user
                })
            });
    };

    render(){
        return(
            <div>
                {// providing `onChange` callback and `query` value from props}
                <input onChange={this.props.onChange} value={this.props.query} type="text"/>
                <button onClick={this.search}>submit</button>
            </div>
        )
    }
}
发布评论

评论列表(0)

  1. 暂无评论