react-redux是配合redux一起使用的,其中核心组件是Provider
Provider是store的提供器,用Provider则store就无需直接引入组件内,而且还可以将一个store公共存储数据区域提供给多个组件
注意一下:之前store相关api导入的是redux, 而Provider,还有相关的api都是导入react-redux,需要npm i先下载
第一步:在index.js入口文件中
import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from "./todolist"
import {Provider} from 'react-redux'
import store from './store'
const App = (
{/*其他的一些组件,可以用同一store*/}
{/**/}
{/**/}
)
ReactDOM.render(App, document.getElementById('root'));
之前我们是在组件中通过store.getState()来获取store中数据中:
constructor(props){ super(props) this.state = store.getState() }
第二步:现在无需通过getState()方法,而是通过connct连接store和组件,并将store的数据映射到store的props上
在todolist写上如下代码:
import React,{Component} from 'react'; import store from './store'
// 别引成redux了
import {connect} from "react_redux" class TodoList extends Component { constructor(props){ super(props) this.state = store.getState() } render() { return () } } // 做连接,如何做连接,就要写映射规则 // mapStateToProps里面写的是props和store中数据的映射规则 // state就是store里面的数据,回调时候会传递过来 const mapStateToProps = (state) => { return { // 组件的props属性对应store中的属性 inputValue: state.inputValue } } // 导出前将TodoList组件和store做连接 export default connect(mapStateToProps,null)(TodoList){/*此时就要用this.props*/} this.props.inputValue}/>
- Dell
以上代码基本逻辑就是:Provider包裹的并与store做连接的组件初始化时候,就会调用一次 mapStateToProps ,将store里面的数据返回给到组件的props。
而且以后每次store里面的数据更新,这个mapStateToProps都会被回调,自动更新inputValue的值.
或者理解成:把props的属性和store.state做了映射,只要state.inputValue发生改变,那么props 对应的属性inputValue就会自动被更新
运行代码:input获得到了store中的数据,如下图所示:
之前我们是用store.dispatch做分发的,但是现在组件并没有引入store,如何做派发action呢?
第三步:changeInputValue,将store.dispatch映射到props中使用
import React,{Component} from 'react' import { connect } from "react-redux" class TodoList extends Component { render() { return () } } // 做连接,如何做连接,就要写映射规则 // mapStateToProps里面写的是props和store中数据的映射规则 // state就是store里面的数据,回调时候会传递过来 const mapStateToProps = (state) => { return { // 这么写就是给组件一个props属性叫inputValue, 并将props属性对应store中的属性 inputValue: state.inputValue } } // 将store.dispatch映射到props中使用 const mapDispatchToProps = (dispatch) => { return { // 这么写就是给组件一个props属性叫changeInputValue,而在这个changeInputValue中可以使用传递过来的dispatch changeInputValue(e){ const action = { type: 'change_input_value', value: e.target.value } dispatch(action) } } } // 导出前将TodoList组件和store做连接 export default connect(mapStateToProps,mapDispatchToProps)(TodoList){/*此时就要用this.props*/} onChange={this.props.changeInputValue} value={this.props.inputValue}/>
第四步:优化
TodoList其实这时是一个UI组件,因为本身并不包含任何逻辑代码,只是接受数据,那么将其改成无状态函数组件会更节约性能
我们说UI组件没有状态,肯定会有一个有状态的容器组件包裹,给他提供数据,其实通过connect方法就会将TodoList这UI组件包裹,导出一个容器组件
export default connect(mapStateToProps, mapDispatchToProps)(TodoList)
import React, {Component} from 'react'
import {connect} from "react-redux"
// class TodoList extends Component {
// render() {
// return (
//
//
// {/*此时就要用this.props*/}
//
//
//
//
// {this.props.list.map((item,index)=>(
//- {item}
// ))}
//
//
// )
// }
// }
const TodoList = (props) => {
const {inputValue,handleButtonClick,handleDelete,list,handleInputChange} = props
return (
{/*此时就要用this.props*/}
{list.map((item, index) => (
- {item}
))}
)
}
// 做连接,如何做连接,就要写映射规则
// mapStateToProps里面写的是props和store中数据的映射规则
// state就是store里面的数据,回调时候会传递过来
const mapStateToProps = (state) => {
return {
// 这么写就是给组件一个props属性叫inputValue, 并将props属性对应store中的属性
inputValue: state.inputValue,
list: state.list
}
}
// 将store.dispatch映射到props中使用
const mapDispatchToProps = (dispatch) => {
return {
// 这么写就是给组件一个props属性叫changeInputValue,而在这个changeInputValue中可以使用传递过来的dispatch
handleInputChange(e) {
const action = {
type: 'change_input_value',
value: e.target.value
}
dispatch(action)
},
handleButtonClick() {
const action = {
type: 'add_item'
}
dispatch(action)
},
handleDelete(index) {
const action = {
type: 'del_item',
index
}
dispatch(action)
}
}
}
// 导出前将TodoList组件和store做连接
export default connect(mapStateToProps, mapDispatchToProps)(TodoList)