使用之前安装react-redux:npm install react-redux
一个项目中用到store中数据的组件有很多,所以应该把他放在App.js
在App.js中引入react-redux。并将子组件使用Provider
组件包裹起来
子组件被Provider组件包裹起来后,每个子组件都能通过一些方法获取到store中的数据,将store传递给每个被包裹的子组件
app.js
import TodoList from './views/TodoList'
import { Provider } from 'react-redux'
import store from './store'
function App() {
return (
<div className="App">
<Provider store={store}>
<TodoList />
</Provider>
</div>
);
}
export default App;
store.js
import { createStore } from 'redux'
import reducer from './reducer'
const store = createStore(
reducer
)
export default store
reducer.js
const defaultState = {
inputVal: 'hello word',
list: []
}
// reducer中需要返回一个函数,接收旧的 state 和 action,返回新的 state
export default (state = defaultState, action) => {
return state
}
那么如何在todolist中使用呢
首先在头部引入react-redux的connect方法
connect方法是将该组件和store连接,通过mapStateToProps来连接
import { connect } from 'react-redux'
class TodoList extends Component {
constructor(props){
super(props)
}
inputValChange = (e) => {
// console.log(e.target.value)
let { changeInputVal } = this.props
changeInputVal(e.target.value)
}
onSubmit = () => {
}
render() {
let { inputVal } = this.props
return (
<div>
<input type="text" onChange={(e) => this.inputValChange(e)} defaultValue={inputVal} />
<button onClick={() => this.onSubmit()}>提交</button>
{/* <ul>
{
list.map((item,index) => {
return <li key={index}>{item}</li>
})
}
</ul> */}
</div>
)
}
}
// 将store中的state数据映射给组件,变成组件的props
const mapStateToProps = (state,ownProps)=> {
return {
inputVal: state.inputVal
}
}
//将dispatch方法映射到组件的props
const mapDispatchToProps = dispatch => {
return {
changeInputVal: (inputVal) => {
dispatch({
type: 'changeInputVal',
payload: inputVal
})
// console.log(inputVal)
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoList)
mapDispatchToProps 和mapStateToProps直接将store中的state数据、dispatch方法映射到组件的props中;
当我们使用了mapDispatchToProps 和mapStateToProps 后,就可以直接通过this.props.xxxx
来获取
如果我们不希望更新数据的话,将前两个值改为null即可
mapStateToProps 第二个参数只要存储状态发生变化或包装器组件收到新的props(基于浅层相等性比较),就会调用该函数
这时候reducer.js代码就需要接收新的state数据并返回了
在上面我的input组件绑定的是defaultValue
,而并不是value,使用value的话会有一个报错,意思是:Input 组件从一个非受控组件变成了一个受控组件
造成这个问题的原因是:初始化时,Input 组件的value值为undefined或者是空。
有两种方法解决,一种是value改为defaultValue
第二种是在reducer.js中,将state进行一次深拷贝,就是下方注释的代码
const defaultState = {
inputVal: 'hello word',
list: []
}
export default (state = defaultState, action) => {
console.log(action)
const { type, payload } = action
if (!payload) return state
if (type === 'changeInputVal') {
return payload
// const newState = JSON.parse(JSON.stringify(state))
// newState.inputVal = payload
// return newState
}
// return state
}