从另一个文件中的功能更改组件状态

时间:2019-03-26 18:57:37

标签: reactjs react-router

我在React领域还很陌生,我不太了解如何实现这项工作。我正在尝试使用来自MediaAPI.js的信息更新App.js的用户状态。我尝试在App组件中创建一个方法,然后使用括号中的JSON数据从MediaAPI.js调用该方法,但它确实无法正常工作。任何帮助将不胜感激!

App.js

class App extends Component {
  state = {
    user: [],
  };


  updateUser = (data) => {
    this.setState({user: data});
  };


  render() {
    return (
        <Router>
            <Nav/>
              <Route exact path="/" component={Login}/>
              <Route exact path="/home" render={(props) => (
                  <Home {...props} picArray={this.state.picArray}/>
              )}/>
              <Route exact path="/profile" component={Profile}/>
              <Route exact path="/single/:id" component={Single}/>
        </Router>
    );
  }
}


export default App;

MediaAPI.js

import App from '../App';

  const login = (username, password) => {
  return fetch(loginUrl, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({username, password})
  }).then(response => response.json()).then(json=> {
    console.log(json);
    App.updateUser(json);
  });
};

2 个答案:

答案 0 :(得分:0)

通过这种方式App.updateUser(json);仅在您的方法是静态的时才有效,而在静态方法中,您无权访问this,有多种方法可以实现:

1:

您可以在App组件内部使用登录功能,如下所示:

class App extends Component {
  state = {
    user: [],
  };

  login = (username, password) => {
    return fetch(loginUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({username, password})
    }).then(response => response.json()).then(data=> {
       this.setState({user: data});
    });
  };


  componentDidMount(data){
    this.login('username', 'password');
  };


  render() {
    return (
        <Router>
            <Nav/>
              <Route exact path="/" component={Login}/>
              <Route exact path="/home" render={(props) => (
                  <Home {...props} picArray={this.state.picArray}/>
              )}/>
              <Route exact path="/profile" component={Profile}/>
              <Route exact path="/single/:id" component={Single}/>
        </Router>
    );
  }
}


export default App;

注意:

您还可以使用Async / await这样简化登录方法:

  login = async (username, password) => {
    const response =  await fetch(loginUrl,
         { method: 'POST', headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({username, password})
    });
    const user =  await response.json();
    this.setState({ user });
  };

注意:

,您也可以这样:

import { login } from 'MediaAPI.js';

class App extends Component {
  state = {
    user: [],
  };

  async componentDidMount(data){
    const user = await login('username', 'password');
    this.setState({ user });
  };


  render() {
    return (
        <Router>
            <Nav/>
              <Route exact path="/" component={Login}/>
              <Route exact path="/home" render={(props) => (
                  <Home {...props} picArray={this.state.picArray}/>
              )}/>
              <Route exact path="/profile" component={Profile}/>
              <Route exact path="/single/:id" component={Single}/>
        </Router>
    );
  }
}


export default App;

MediaAPI.js

   export const login = (username, password) => {
      return fetch(loginUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({username, password})
      }).then(response => response.json());
    };

2:

您可以创建一个组件,然后在该组件上使用App并为其设置ref,然后使用updateUser方法。

----还有其他方法,但我认为这两种方法最好。

答案 1 :(得分:0)

据我所知,我认为您的方法是一种反模式。下面是我的处理方法。


import mediaAPI from 'MediaAPI'

class App extends Component {
  state = {
    user: [],
  };

  // this is a React lifecycle hook that will be
  // called when the component has mounted.
  componentDidMount() {
    mediaAPI()
      .then(res => res.json())
      .then(this.setUserData)
  }


  setUserData = (data) => {
    this.setState({user: data});
  };


  render() {
    return (
        <Router>
            <Nav/>
              <Route exact path="/" component={Login}/>
              <Route exact path="/home" render={(props) => (
                  <Home {...props} picArray={this.state.picArray}/>
              )}/>
              <Route exact path="/profile" component={Profile}/>
              <Route exact path="/single/:id" component={Single}/>
        </Router>
    );
  }
}