本教程总共5篇,每日更新一篇,请关注我们!你可以进入历史消息查看以往文章,也敬请期待我们的新文章!
1、React第三方组件2(状态管理之Refast的使用①简单使用)---2018.01.29
2、React第三方组件2(状态管理之Refast的使用②异步修改state)---2018.01.30
3、React第三方组件2(状态管理之Refast的使用③扩展ctx)---2018.02.31
4、React第三方组件2(状态管理之Refast的使用④中间件middleware使用)---2018.02.01
5、React第三方组件2(状态管理之Refast的使用⑤LogicRender使用)---2018.02.02
开发环境:Windows 8,node v8.9.1,npm 5.5.1,WebStorm 2017.2.2
Refast 是阿里团队贡献的一款react状态管理工具,其简单实用性受到用户一致好评!确实做到了(5分钟就能学会的 React 组件状态管理工具)!
文档地址:http://doc.refast.cn/
我们今天来用下Refast!(不讲太深,简单用下)
1、我们还是新建一个路由页面 demo3:
目录结构如下:
2、新建Index.jsx 文件
import React from 'react'; import TodoList from './TodoList'; const Index = () => <TodoList/> ; export default Index;
3.把demo1下的TodoList.jsx 复制到 demo3 下
4、安装依赖:
npm i -S refast
5、先在demo3下建立一个 logic.js 文件
把TodoList.jsx 里的两个方法,复制到logic,js中
handleAdd() { let item = this.refs['todoInput'].value; if (item) { let list = this.state.list; list.push({id: list.length + 1, title: item, status: 1}); this.setState({list: list}, () => console.log(this.state.list)) } else { alert('不能为空') } } handleItemEdit(id, status) { let list = this.state.list; list.find(data => data.id === id).status = status; this.setState({list: list}) }
如下:
// Refast 使用 logic.js 中 defaults 方法的返回值初始化组件的 state export default { // defaults 的参数 props 是组件初始化时的 props // defaults 函数返回的对象会用来初始化组件的 state defaults(props) { return { list: [] } }, handleAdd(ctx, title) { if (title) { let list = ctx.getState().list; list.push({id: list.length + 1, title: title, status: 1}); ctx.setState({list: list}); } else { alert('不能为空') } }, handleItemEdit(ctx, someState) { let {id, status} = someState, list = ctx.getState().list; list.find(data => data.id === id).status = status; ctx.setState({list: list}) } }
这两个方法也叫 Action,当 Logic 与 组件联接后,就可以通过组件的 dispatch 方法直接调用 Logic 中的 Action 了。
可以在TodoList中这么调用:
this.dispatch('handleAdd', 'xxxxxx')}
通过dispatch 给方法传参(也可以不传)。
被 dispatch 的 Action,其第一个参数始终是 context (下简称 ctx)。 此外,ctx 还封装了以下几个通用方法:
ctx.setState 设置组件的 state, 用法与组件的 setState 相同
ctx.getState 获取组件当前的 state
ctx.getProps 获取组件当前的 props
所有你也可以写成这样:
// Refast 使用 logic.js 中 defaults 方法的返回值初始化组件的 state export default { // defaults 的参数 props 是组件初始化时的 props // defaults 函数返回的对象会用来初始化组件的 state defaults(props) { return { list: [] } }, handleAdd({getState, setState}, title) { if (title) { let list = getState().list; list.push({id: list.length + 1, title: title, status: 1}); setState({list: list}); } else { alert('不能为空') } }, handleItemEdit({getState, setState}, someState) { let {id, status} = someState, list = getState().list; list.find(data => data.id === id).status = status; setState({list: list}) } }
6、改造下 TodoList.jsx
import React from 'react'; import {Component} from 'refast'; // 引入 logic.js import logic from './logic'; import '../../../public/css/todoList.pcss'; class TodoList extends Component { constructor(props) { super(props, logic); } render() { let {list} = this.state; let LiCont = ({data}) => <li> {data.title} <button onClick={() => this.dispatch('handleItemEdit', { id: data.id, status: data.status === 1 ? 0 : 1 })} className={data.status === 1 ? "del" : "recovery"}> {data.status === 1 ? "删除" : "恢复"} </button> </li> ; let ListCont = ({type}) => <div className="list"> { list.map(data => [ type === 0 ? <LiCont data={data} key={data.id}/> : type === 1 && data.status === 1 ? <LiCont data={data} key={data.id}/> : type === 2 && data.status === 0 ? <LiCont data={data} key={data.id}/> : null ] ) } </div> ; return ( <div className="todoList"> <input type="text" ref="todoInput"/> <button onClick={() => this.dispatch('handleAdd', this.refs['todoInput'].value)}>添加</button> <div className="cont"> <div className="box"> 全部 <ListCont type={0}/> </div> <div className="box"> 未删除 <ListCont type={1}/> </div> <div className="box"> 已删除 <ListCont type={2}/> </div> </div> </div> ); } } export default TodoList;
使用 Refast 的 Component 替代 React 的 Component
引入logic
通过 super 绑定 logic
看下浏览器,应该一切OK!
Refast主要是做了解耦,各管各的!
如果你需要再拆分组件,也可以这样写:
我们还是新建一个页面demo4
重复新建demo3一样的步骤!
TodoList.jsx:
import React from 'react'; import {Component} from 'refast'; // 引入 logic.js import logic from './logic'; import List from './List'; import '../../../public/css/todoList.pcss'; class TodoList extends Component { constructor(props) { super(props, logic); } render() { let {list} = this.state, {dispatch} = this; return ( <div className="todoList"> <input type="text" ref="todoInput"/> <button onClick={() => this.dispatch('handleAdd', this.refs['todoInput'].value)}>添加</button> <div className="cont"> <div className="box"> 全部 <List type={0} list={list} dispatch={dispatch}/> </div> <div className="box"> 未删除 <List type={1} list={list} dispatch={dispatch}/> </div> <div className="box"> 已删除 <List type={2} list={list} dispatch={dispatch}/> </div> </div> </div> ); } } export default TodoList;
List.jsx :
import React from 'react'; const LiCont = ({data, dispatch}) => <li> {data.title} <button onClick={() => dispatch('handleItemEdit', { id: data.id, status: data.status === 1 ? 0 : 1 })} className={data.status === 1 ? "del" : "recovery"}> {data.status === 1 ? "删除" : "恢复"} </button> </li> ; const List = ({dispatch, list, type}) => <div className="list"> { list.map(data => [ type === 0 ? <LiCont data={data} dispatch={dispatch} key={data.id}/> : type === 1 && data.status === 1 ? <LiCont data={data} dispatch={dispatch} key={data.id}/> : type === 2 && data.status === 0 ? <LiCont data={data} dispatch={dispatch} key={data.id}/> : null ] ) } </div> ; export default List;
logic.js
export default { defaults(props) { return { list: [] } }, handleAdd({getState, setState}, title) { if (title) { let list = getState().list; list.push({id: list.length + 1, title: title, status: 1}); setState({list: list}); } else { alert('不能为空') } }, handleItemEdit({getState, setState}, someState) { let {id, status} = someState, list = getState().list; list.find(data => data.id === id).status = status; setState({list: list}) } }
目录结果如下:
7、测试
我们在 demo 下 Index.jsx中加入这两个路由
运行下浏览器,一切ok
import React from 'react'; import {HashRouter, Route, NavLink, Redirect} from 'react-router-dom' import {BundleFun} from '../common/Bundle' import Dome1 from './demo1/Demo1.bundle' import Dome2 from './demo2/Demo2.bundle' import Dome3 from './demo3/Index' import Dome4 from './demo4/Index' import '../../public/css/demo.pcss' const Index = () => <HashRouter> <div className="content"> <div className="nav"> <NavLink to="/Dome1" activeClassName="selected" exact>demo1</NavLink> <NavLink to="/Dome2" activeClassName="selected">demo2</NavLink> <NavLink to="/Dome3" activeClassName="selected">demo3</NavLink> <NavLink to="/Dome4" activeClassName="selected">demo4</NavLink> </div> <Route exact path="/" render={() => (<Redirect to="/Dome1"/>)}/> <Route path="/Dome1" component={() => BundleFun(Dome1)}/> <Route path="/Dome2" component={(props) => BundleFun(Dome2, props)}/> <Route path="/Dome3" component={Dome3}/> <Route path="/Dome4" component={Dome4}/> </div> </HashRouter> ;
在浏览器中,参看下:
两种写法都OK!!!
本文完
禁止擅自转载,如需转载请在公众号中留言联系我们!
感谢童鞋们支持!
如果你有什么问题,可以在下方留言给我们!