我正在React中学习Redux。我正在使用redux-thunk。我有如下操作
export const login = (value, history) => dispatch => {
Axios.post('/api/users/login', value)
.then(response => {
dispatch(getAddress()); // I am calling like this
})
.catch(error => {});
}
我的地址操作如下所示
export const getAddress = () => dispatch => {
Axios.get('/api/address')
.then(response => {
dispatch({
type: 'getAddresses',
payload: response.data
});
})
.catch(function (error) {});
}
我试图在组件中显示值,如下所示
render() {
return (
<div>Hello {console.log(this.props)}</div> // I am getting empty object
);
}
const mapStateToProps = state => ({
addresses: state.address
});
export default connect(mapStateToProps)(Dashboard);
但是我得到的是空对象。
我想在登录后将用户重定向到显示地址的仪表板。我该怎么办?
答案 0 :(得分:2)
Redux thunk中间件允许通过dispatch
进行链接,dispatch(...)
返回已调度的动作,即,如果诺言链未中断,则为诺言:
export const login = (value, history) => dispatch => {
return Axios.post('/api/users/login', value) // return!
.then(response => {
return dispatch(getAddress()); // return!
})
.catch(error => {});
}
export const getAddress = () => dispatch => {
return Axios.get('/api/address') // return!
.then(response => {
return dispatch({ // return!
type: 'getAddresses',
payload: response.data
});
})
.catch(function (error) {});
}
初始动作应分派到某个地方。在原始Redux设置中,可以在商店定义后分派:
store.dispatch(login());
在React Redux设置中,组件是Redux数据流的组成部分。异步重传是一个副作用,应在componentDidMount
中调度一次。如果采取初步行动,则应在父组件中分派:
@connect()
class App extends Component {
componentDidMount() {
return this.props.dispatch(login());
}
render() {
return !this.props.addresses ? 'Loading' : <Dashboard />
}
}
这里是demo。
答案 1 :(得分:2)
因此,这需要对具有“副作用”的Redux流程进行非常基本的介绍。
定义警报!在Redux中,诸如API调用之类的东西称为“边”。 效果。这是因为您正在做一些典型的事情 单向数据流。
希望您已了解此流程。我特别担心您似乎困惑的特定部分。 因此,在您的代码中,您尝试执行此操作。
then(response => {
return dispatch(getAddress());
})
您的代码在这里试图做的是,它正在试图“分发”副作用。错了!
调度几乎总是一个普通的可序列化的旧JS对象。通常,您将具有这样的成见结构。您似乎在另一个其他人获得的地址呼叫中。
{
type: 'GET_ADDRESS_REQUEST_SUCCESS',
payload: {}
}
因此执行任务的正确方法是这样的。想一想,当发生各种事情时,调度操作就像发出信号一样。
export const login = (value, history) => dispatch => {
Axios.post('/api/users/login', value)
.then(response => {
//Send out a success signal
dispatch({
type: 'loginSuccess',
payload: response.data
});
//Now that I have logged in successfully I can call for my address
//This is simply how you call an action within an action!
getAddress();
}).catch(error => {
//login failed signal
dispatch({
type: 'loginFailed',
payload: response
}); // I am calling like this
});
}
export const getAddress = () => dispatch => {
Axios.get('/api/address')
.then(response => {
//Get address success signal
dispatch({
type: 'getAddressSuccess',
payload: response.data
});
}).catch(function (error) {
//Get addresses failed signal
dispatch({
type: 'getAddressFailed',
payload: error
});
});
}
下一个重要部分是减速器,您未在此处包括!如果动作发出信号,则将减速器视为接收器,接收并处理该信号。 减速器将根据部署的操作来更新现有状态。
export default function appReducer(state, action) {
switch (action.type) {
case 'getAddressSuccess': //Waiting on the signal!
return Object.assign({},state,{address : action.payload}
//Set the proper address based on your payload from the api call
default:
return state
}
}
您还应该正确设置redux thunk配置,以使其完全起作用。 干杯!
============ EDIT ============
因此,在检查代码库后,您已使用Combine Reducer将多个reducer融合在一起。
import { combineReducers } from 'redux';
import authReducer from './authReducer';
import addressReducer from './addressReducer';
const rootReducer = combineReducers({
authReducer,
addressReducer
});
export default rootReducer;
因此在mapsStateToProps中,您的商店状态将如下所示
{
authReducer: {
// state managed by the authReducer
},
addressReducer: {
address: 'Test Streat, London'
}
}
因此,将您的mapStateToProps更改如下:
const mapStateToProps = state => ({
addresses: state.addressReducer.address
});
export default connect(mapStateToProps)(Dashboard);