React Redux
来源:互联网 发布:尼泊尔弯刀数据图纸 编辑:程序博客网 时间:2024/05/18 00:17
React
React有两个重点props和state。
props
可以获取组件的属性,例如
class App extends Component{ render(){ return ( <h1>hello {this.props.name}</h1> ) } }ReactDom.render( <App name="小明"/>, mountDom);
这样标签的name属性可以通过props传入到App这个class中进行相关操作。他可以用来做数据的显示,例如想要封装一个Table组件则可以规定一个dataSource属性来传入数据源,内部通过解析这个数组进行遍历展示,封装好后的写法类似于这样就可以完成展示:
let ds=[ {name:'张三',age:22}, {name:'李四',age:25}]<Table dataSource={ds}/>
由此我们可以看出props用来传递一些展示的数据是非常好用的。
state
state是react的一个核心,我们知道组件都是调用render函数渲染的,在初次加载页面的时候会渲染一次。之后如果想要重新渲染,则需要组件的state发生改变的时候才会再次渲染。
class App extends Component{ getInitialState(){ return {num:0}; } render(){ return ( <h1>{this.state.num}</h1> <button onClick={e=>this.handleClick(e)}>add</button> ) } handleClick(e){ this.setState({num:this.state.num+1}) }}
上面例子是点击按钮使state产生了变化,而state变化后会重新调用render函数进行渲染,进而显示的数产生了变化。
我们发现如果是需要变化的数据展示页面,需要用state来存这些数据,数据的变化才会导致重新渲染,结合之前的props所以最后一般的解决方案是这样:单纯的展示组件就用props存储数据,而需要产生动态变化的时候就在这个组件外面套一个组件。
class Show extends Component{ render(){ return <h1>{this.props.num}</h1>; }}class App extends Component{ getInitialState(){ return {num:0}; } render(){ return ( <Show num={this.state.num}> <button onClick={e=>this.handleClick(e)}>add</button> ) } handleClick(e){ this.setState({num:this.state.num+1}) }}
Redux
react中的state在任何一个内部的函数中都可以通过调用this.setState()
方法进行改动,也就意味着这些地方都能进行重新渲染。这使得渲染产生的时机不好把握。另外每个组件都有一个state嵌套增多的时候,会搞得自己晕头转向。当这个组件功能变多的时候问题变得更严重。
Redux就提出了一种想法:把整个应用的所有state都存到一个地方,通过在特定入口触发事件才能引起state的改变。
action
这个事件叫做action他就是一个json对象规定了必须有个字段叫type,例如一个增加用户的事件可能是这样:
{ type:"USER_ADD", user:{name:"张三",age:33}}
reducer
处理事件的第一步就是更新state,这一步处理叫做reduce,reducer就是一个函数规定了必须有俩参数一个是当前的state,一个是action;并且规定了返回值是因为这个action导致的变化后的state,例如增加用户对应的reducer大致如下:
function myReducer(state={users:[]},action){ if(action.type == "USER_ADD") let newstate =Object.assign({}, state); newstate.users.push(action.user); return newstate; return state;}
注意这里参数中state={users:[]}
的意思是如果没有传state参数只传了action这一个参数,state默认值是{users:[]}。这是规定state初始值的一种写法。 Object.assign
这里本来可以直接写成state.users.push(action.user)
但是是改变了原来的state,可能在同时操作的时候出现问题,这里的写法是复制了一份state,不影响原state。
store
我们上面说了事件action以及处理action更新state用的reducer,不过state到底存在哪里呢?我们每次触发事件都要人为调用reducer函数么?答案是不用,store帮我们来做这些事情。
通过reducer来创建store,创建后就能直接获取state通过getState
方法,之前的[]被设为初始值了,会被返回。
触发事件则通过dispatch(action)
函数,事件触发后会 自动调用reducer更新state,然后触发回调函数。回调函数通过subscribe(callback)
函数进行设置,改函数的返回值是注销这个回调函数的函数。
import { createStore } from 'redux'let store = createStore(myReducer);console.log(store.getState()); //[]let unsubscribe = store.subscribe(() => console.log(store.getState()))let addAction={ type:"USER_ADD", user:{name:"张三",age:33}}store.dispatch(addAction); //事件触发后state更新然后触发回调函数,打印了state的值unsubscribe();
通过上面这个例子,我们大体明白了redux的工作流程,通过这样的写法,我们能够将state
汇总起来,所有的事件触发例如点击按钮,都通过store.dispatch(action)
进行触发。不用再在每个组件中写处理函数,只需要在一个文件中集中写好 多个reducer。
React-Redux
Redux是一种集中处理集中存储state的思想,他并不是react的扩展,他也可以用在angularjs vue等。如果要在React中使用还需要安装react-redux,上面的例子中是手动调用store.dispatch
触发事件的,react中则可能是在某个onClick
函数中触发事件。上述的监听state的变化是用了store.subscribe
进行订阅的state的变化,而react中需要将store中的state绑定到组件的state上,这些工作都交给react-redux帮我们来做:
import { Provider,connect } from 'react-redux'import { createStore } from 'redux'import { render } from 'react-dom'//声明storelet store = createStore(myReducer);//展示Users的组件class App extends Component{ render(){ //在调用connect之后,会自动绑定一个dispatch和自定义绑定过来的users const { dispatch,users } = this.props let content =users.map(it=>{return <tr>{it.name}</tr><tr>it.age</tr>}) return ( <table> <tr><th>name</th><th>age</th></tr> {content} </table> <button onClick={e=>dispatch(addAction)}>add</button> ) } }//将state的users绑定到props中function select(state) { return { users: state.users };}//调用connect函数完成dispatch和users的绑定,绑定后的组件名为Conlet Con = connect(select)(App)//通过Provider将store注入进来,此时所有react组件的state都存放在这里render( <Provider store={store}> <Con /> </Provider>, document.getElementById("main"))
整个流程是首先完成了store.state和react中state的联系;
渲染Con组件,因为初始状态的users是[],所以表格有0行数据;
点击add按钮,触发了添加用户的action;
reducer中处理,在users属性中追加了这个user;
store.state状态发生了变化,自动绑定到react,认为需要重新渲染了,然后重新渲染了Don;
Don中的users属性更新,并显示在表格中,多了一行。
- react+redux+react-redux
- redux react-redux
- Redux(三: React-Redux)
- react-redux
- React + Redux
- React&Redux
- react-redux
- React Redux
- react-redux
- react-redux
- React-Redux
- React Redux
- react + redux + react-redux 心得
- React和Redux的连接react-redux
- React和Redux的连接react-redux
- React和Redux的连接react-redux
- React和Redux的连接react-redux
- React和Redux的连接react-redux
- git常用命令讲解
- 最难的问题
- 线程安全的单例模式
- php递归实现无限级分类树(牛逼)
- node.js通俗解释
- React Redux
- Android studio 导入 aidl
- 1057. 数零壹(20) PAT乙级真题
- sping是怎么处理线程并发的
- Django基本命令
- String 不可变字符串(字符串常量)
- android 短信查询、头像、联系人名称(支持会话和短信)__接上篇
- pycharm、mysql、virtualenv虚拟机环境、python3、Django、vue开发环境搭建
- python2.7使用csv