Redux
三个API:createStore() combineReducers() applyMiddleware()
三个原则:store是只读的、单向数据流、store只能通过纯函数reducer()修改
三个概念:store、reducer、action
redux定义
// npm i redux -S import { createStore } from 'redux'; const initState = { msg: 'hello redux', list: [] } function reducer (state = initState, action) { let newState = JSON.parse(JSON.stringify(state)); switch (action.type) { case 'add': newState.msg += action.payload; break; default: break; } return newState; } const store = createStore(reducer); export default store;
redux引入
import { Provider } from 'react-redux'; // Provider包裹app组件 <Provider store={store}> <div className="app"> <Layout /> </div> </Provider>
redux组件内使用
import React from 'react'; // import { connect } from 'react-redux'; import { useSelector, useDispatch } from 'react-redux'; // 1.使用高阶函数connect使用redux // const TestRedux = props => { // console.log('testredux props',props); // return ( // <div> // <h1>测试Redux</h1> // <h2>{ props.msg }</h2> // <button onClick={props.changeMsg}>修改msg</button> // </div> // ) // } // function mapStateToProps (store) { // return { // msg: store.msg // } // } // function mapDispatchToProps (dispatch) { // return { // changeMsg: () => dispatch({ type: 'add', payload: 'hello 2021' }) // } // } // export default connect(mapStateToProps,mapDispatchToProps)(TestRedux); // 2.使用Hooks api的方式使用store export default props => { const msg = useSelector(store => store.msg); const dispatch = useDispatch(); const handleClick = () => { dispatch({ type: 'add', payload: 'hello Hooks redux' }); } return ( <div> <h1>测试Redux</h1> <h2>{ msg }</h2> <button onClick={handleClick}>修改msg</button> </div> ) }
redux只支持dispatch(action)派发同步的action完成一次异步的action,需要被分解成两次同步的action
function getMusic (params) { return function (dispatch) { fetchMusic(params).then(res => { dispatch({ type: 'music', payload: res.song.list }) }) } } dispatch(getMusic(params)); // 此时报错需要使用异步的action必须使用applyMiddleware // dispatch(action)(要求action只能为普通的对象),当react组件中使用dispatch(fn)触发调接口,此时的fn不是plain object ,redux的store收到一个不是plain object的action时,就会报错 // 解决方法 // 当我们在组件中dispatch(xxx)时,thunk对xxx进行判断,如果xxx是plain object,不做任何处理,那么redux的store将收到这个action。如果xxx是function,那么在thunk中,将拦截掉这个xxx,并调用这个xxx()方法。 npm i redux-thunk -S import thunk from 'redux-thunk'; const store = createStore(reducer,applyMiddleware(thunk));