我正在学习redux并做出反应,而且我在道具初始化的良好实践方面遇到了一些问题。
事实上,我的路线如下:
/pokemons/:name
以下是相关部分:
import React from 'react';
import {connect} from 'react-redux';
import {showDetail} from './../../redux/modules/pokemons';
export class PokeDetail extends React.Component{
render(){
return(
<div>
{this.currentPokemon.name}
</div>
)
}
}
const mapStateToProps = state => ({
currentPokemon:state.pokemons.currentPokemon
});
export default connect((mapStateToProps),{
showDetail
})(PokeDetail);
事实是我完全不知道 when / where 来发送我的操作以更改我的应用状态。事实上,我什么时候应该发送我的“showDetail('myPokemonName')”,以便currentPokemon状态会改变,我的应用程序可以工作?
如果可能,我需要一些好的做法
感谢您的帮助
编辑:
My PokeView :
import React from 'react';
import {connect} from 'react-redux';
import {loadRemoteAction} from './../../redux/modules/pokemons';
import {Link} from 'react-router';
export class PokeView extends React.Component {
render(){
let i = 0;
return (
<div>
<h4>Super page</h4>
<button onClick={this.props.loadRemoteAction}>Start</button>
<ul>
{
this.props.pokemons.map(item => {
i++;
return <li key={i}><Link to={`/pokemons/${item.name}`}>{item.name}</Link></li>
})
}
</ul>
</div>
);
}
}
const mapStateToProps = state => ({
pokemons : state.pokemons.pokemons
});
export default connect((mapStateToProps), {
loadRemoteAction
})(PokeView);
我的行动/减速机:
import immutable from 'immutable';
/**
* Action part
*/
export const LOAD_REMOTE = 'LOAD_REMOTE';
export const SHOW_DETAIL = 'SHOW_DETAIL';
export function loadRemoteAction() {
return dispatch => {
fetch('http://pokeapi.co/api/v2/pokemon/')
.then(res => res.json())
.then(res => dispatch({
type:LOAD_REMOTE,
payload:res.results
}));
};
}
export function showDetail(name){
return {
type:SHOW_DETAIL,
payload:name
}
}
/**
* Reducer part
*/
const ACTION_HANDLER = {
[LOAD_REMOTE] : (state, action) => {
if(action.payload) return Object.assign({},state,{pokemons:state.pokemons.concat(action.payload)});
return state;
},
[SHOW_DETAIL] : (state, action) =>{
let currentPokemon;
for(const pkm of state.pokemons){
if(pkm.name === action.payload) currentPokemon = pkm;
}
if(action.payload) return Object.assign({},state,{currentPokemon:currentPokemon});
return state
}
}
const initialState = {pokemons:immutable.fromJS([]), currentPokemon:immutable.fromJS({name:''})};
export default function pokemonReducer (state = initialState, action) {
const handler = ACTION_HANDLER[action.type]
return handler ? handler(state, action) : state
}
答案 0 :(得分:3)
一般来说,行动就是世界上发生了某些事情 - 这通常是用户所做的事情,或者例如从后端到ajax调用的异步回答。在这些情况下,您希望发送操作(包含有关更改内容的信息),以便相应地更新状态树。
在您的情况下,如果您在屏幕上的其他位置显示Pokemons列表,并且用户点击其中一个,那么该点击会将点击的Pokemon保存到状态树,而您的PokeDetail
组件将会然后获取此信息并显示所选口袋妖怪的详细信息。
在您的情况下,PokeView
渲染功能可能如下所示:
export class PokeView extends React.Component {
render(){
return (
<div>
<h4>Super page</h4>
<button onClick={this.props.loadRemoteAction}>Start</button>
<ul>
{
this.props.pokemons.map((item, i) => <li key={i}><button onClick={this.props.dispatch(showDetail(item.name))}>{item.name}</button></li> )
}
</ul>
</div>
);
}
}
并且PokeDetail
类可能如下所示:
export class PokeDetail extends React.Component{
render(){
return <div>{this.props.currentPokemon.name}</div>;
}
}
另一个问题是,信息最初如何进入我的应用程序?如果数据是静态的,您可以将其添加到初始状态树(通常将其作为默认参数传递给reducer函数),或者您可以通过Ajax调用从后端查询数据。后者可以在组件的componentDidMount
生命周期方法中完成。 (为此,您需要redux-thunk
才能使操作与回调和后端的异步应答一起工作。)
答案 1 :(得分:0)
您应该在componentWillMount函数中调用 showDetail 操作。
import React from 'react';
import {connect} from 'react-redux';
import {showDetail} from './../../redux/modules/pokemons';
export class PokeDetail extends React.Component{
componentWillMount() {
// If you are using react-router, route params will be in `params` property object.
const pokemonId = this.props.params.id;
this.props.showDetail(pokemonId);
}
componentWillReceiveProps(nextProps) {
// Also you may want to update your component when url was changed.
if (nextProps.params.id !== this.props.params.id) {
this.props.showDetail(nextProps.params.id);
}
}
render(){
return(
<div>
{this.currentPokemon.name}
</div>
)
}
}
const mapStateToProps = state => ({
currentPokemon:state.pokemons.currentPokemon
});
export default connect((mapStateToProps),{
showDetail
})(PokeDetail);
当您的组件正在挂载(或更新)时,您正在使用pokemon id调用您的操作。接下来,您的商店将会更新,您将在PokeDetail组件中收到所需的道具。
对于异步操作,您可能需要redux-thunk包。
答案 2 :(得分:-1)
您可以使用redux-async-connect包。您可以找到此包here的示例用法。