#reactjs #react-router
#reactjs #react-маршрутизатор
Вопрос:
Я совсем новичок в React и не совсем понимаю, как заставить это работать. Я пытаюсь обновить App.js состояние пользователя с информацией, поступающей из MediaAPI.js . Я попытался создать метод в компоненте приложения, а затем вызвать метод из MediaAPI.js с данными JSON в скобках, но на самом деле это не работает. Любая помощь будет высоко оценена!
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);
});
};
Ответ №1:
Этот способ App.updateUser(json);
работает только тогда, когда ваш метод статичен, а в статическом методе у вас нет доступа к this
, есть способы добиться этого:
1:
вы можете использовать свою функцию входа в свой компонент приложения следующим образом :
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 и задать ему ссылку, а затем использовать updateUser
метод.
—- есть другие способы, но я думаю, что эти два являются лучшими.
Ответ №2:
Насколько я знаю, я бы сказал, что ваш подход является антишаблоном. Ниже я бы подошел к этому.
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>
);
}
}