🚩🚩🚩
💎个人主页: 阿选不出来
💨💨💨
💎个人简介: 一名大二在校生,学习方向前端,不定时更新自己学习道路上的一些笔记.
💨💨💨
💎目前开发的专栏: JS 🍭Vue🍭React🍭
💨💨💨
React——redux
Redux 是 JavaScript 状态容器,提供可预测化的状态管理。
redux的使用场景
redux的三大原则
下载redux包
npm i redux
代码结构

store.js文件专门用于创建并配置store并暴露
//引入createstore,用于创建store对象
import {legacy_createStore as createStore} from 'redux'
// 引入reducer
import reducer from './reducers'
const store = createStore(reducer)
export default store
actions文件夹存放多个为指定组件生成的action对象。
reducers文件夹存放多个为指定组件服务的reducer纯函数。
constant.js文件用于定义action对象中type类型的常量值,便于管理,防止单词的拼写错误。
例:
export const INCREMENT = 'increment'
Redux的工作流

Action 是把数据从应用(译者注:这里之所以不叫 view 是因为这些数据有可能是服务器响应,用户输入或其它非 view 的数据 )传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch() 将 action 传到 store。
const ADD_TODO = 'ADD_TODO'
{
type: ADD_TODO,
data: 'Bilid my first Redux app'
}
action本质为JavaScript普通对象。
action内必须包含 type 属性,值为字符串,表示将要执行的动作,作为唯一标识。
除 type属性外,action对象的结构完全由你自己决定,通常会传入 data属性,值为某个组件向reducer函数操作state时传的参数。
在模块化开发中,一个组件可能会需要多个action对象,通常按照下方的写法。
const INCREMENT = 'INCREMENT'
export const increment = data =>({type: INCREMENT,data})
...
异步action
例如:点击一个按钮,三秒后让一个count数值加一。
当点击按钮后,组件内通过 store.dispatch 将action对象派发给store。
我们在action中返回一个定时器,3秒后调用同步action触发 dispatch执行加动作。
export const incrementAsync = (data,time) =>{
return (dispatch)=>{
setTimeOut(()=>{
dispatch(increment(data))
})
}
}
由于redux本身不支持异步操作。react给我们提供了一个插件 redux-thunk 可以让redux拥有异步操作的能力。
用法:
store.js文件下
import {legacy_createStore as createStore,applyMiddleware} from 'redux'
import thunk from 'redux-thunk
...
export default createStore(reducer,applyMiddleware(thunk))
reducer用于将store发过来的action完成并将结果返回给store,他有两个作用:初始化store和更新store。
reducer接收两个参数preState(旧状态)和action(动作)并返回一个newState(新状态)。
(previousState, action) => newState
初始化状态
const initState = 0 //初始化状态
reducer纯函数
function count(preState=initState,action){
// 从actions对象中获取:type,data
const {type,data} = action
//根据type决定如何加工数据
switch(type){
case INCREMENT:
return xxx
...
default:
return preState
}
}
注意:redux的reducer是一个纯函数。纯函数是一类特别的函数。
纯函数的规则:
- 不能改写参数数据。
- 不会产生任何副作用,例如网络请求,输入和输出设备。
- 不能调用Date.now()或Math.random()等不纯的方法。
例如:当我们要对store里的一个数组添加一个对象时:
错误的写法:
preState.unshift(data)
此时,preState这个实参被改写了,reducer不在是纯函数。
正确的写法:
使用对象展开运算符
[data,...preState] 创建了一个新数组。
combineReducers
Redux应用中只有一个单一的store。当多个组件都需要用到store时,便于数据逻辑处理,我们需要使用reducer组合。
redux提供了 combineReducers()工具类,组合多个reducer。
import {combineReducers} from 'redux'
//引入多个reducer
import reducer1 from './reducer1'
import reducer2 from './reducer2'
...
export default combineReducers({
reducer1,
reducer2
})
前文我们知道了使用action描述“发生了什么”,使用 reducers来根据action更新state的用法。
而 store 就是action 和 reducer 之间的桥梁。
store的创建
//引入createstore,用于创建store对象
import {legacy_createStore as createStore} from 'redux'
// 引入reducer
import reducer from './reducers'
const store = createStore(reducer)
createStore第一个参数传入reducer,第二个参数为可选的,用于设置state初始状态。
Store的职责
getState()方法获取state;这里需要再强调一下:Redux 和 React 之间没有关系。Redux 支持 React、Angular、Ember、jQuery 甚至纯 JavaScript。
为了让用户监听应用数据改变,Store 允许使用store.subscribe方法设置监听函数,一旦 State 发生变化,就自动执行这个函数。
在src/index.js入口文件中:
import store from './redux/store'
...
store.subscribe(()=>{
root.render(<App/>)
})
本库并不是 Redux 内置,需要单独安装,是Redux官方提供的React绑定库。
安装
npm i react-redux
redux将组件分为了UI组件和容器组件两类:
<Provider store> 使组件层级中的 connect() 方法都能够获得 Redux store。
在src/index.jsx文件下:
...
root.render(
<Provider store={store}
<App/>
</Provider>)
目的:让 <App> 所有的后代容器组件都能接收到store。
用于连接React组件与Redux store。
connect(mapStateToProps,mapDispatchToProps)
mapStateToProps(state, [ownProps]): stateProps] (Function)
mapDispatchToProps(dispatch, [ownProps])
映射操作状态的方法。
mapDispatchToProps可以是一个Function,也可以是Object,作用是绑定action创建函数到props上。
如果传递的是一个对象,那么每个定义在该对象的函数都将被当作Redux action creator,而且这个对象会与 Reduxstore绑定在一起,其中所定义的方法名将作为属性名,合并到组件的 props 中;
如果传递的是一个函数,该函数将接收一个 dispatch 函数,然后由你来决定如何返回一个对象,这个对象通过 dispatch 函数与action creator 以某种方式绑定在一起。
例:
头部的引入:
import React, { Component } from 'react'
import {connect} from 'react-redux'
import {
increment,
decrement,
} from '../../redux/actions/count'
mapDispatchToProps返回值为函数时:
connect(
state=>(count:state.count),
dispatch=>({
increment:number=> dispatch(increment(number)),
decrement:number=> dispatch(decrement(number))
})
)
mapDispatchToProps返回值为对象时:
采用了对象的简写形式
connect(
state=>(count:state.count),
{increment,decrement}
)
react-redux的开发者工具
redux-devtools-extensionredux这个插件是官方提供的可以查看状态的ui插件,让我们在很多组件的情况下,也能知道每个组件的数据情况,非常贴心。
安装
npm i redux-devtools-extension
配置
import {composeWithDevTools} from 'redux-devtools-extension'
...
const store = createStore(reducer,composeWithDevTools(applyMiddleware(thunk)))
我有一个将某些事件写入队列的Rails3应用。现在我想在服务器上创建一个服务,每x秒轮询一次队列,并按计划执行其他任务。除了创建ruby脚本并通过cron作业运行它之外,还有其他稳定的替代方案吗? 最佳答案 尽管启动基于Rails的持久任务是一种选择,但您可能希望查看更有序的系统,例如delayed_job或Starling管理您的工作量。我建议不要在cron中运行某些东西,因为启动整个Rails堆栈的开销可能很大。每隔几秒运行一次它是不切实际的,因为Rails上的启动时间通常为5-15秒,具体取决于您的硬件。不过,每天这样做几
是否可以在单个事件机器中运行多个服务器?我的意思是,多个服务可以由一个客户端连接同时使用。例如,登录服务器对用户进行身份验证,然后用户可以同时使用聊天室和简单的游戏,例如带有单个客户端套接字的跳棋?或者我是否需要为每个服务使用多个事件机器react器? 最佳答案 我试过了,它正在工作:#!/usr/bin/envrubyrequire'eventmachine'moduleEchoServerdefpost_initputs"--someoneconnectedtotheechoserver!"enddefreceive_datad
React添加Class的方式在vue中添加class是一件非常简单的事情:你可以通过传入一个对象,通过布尔值决定是否添加类:button:class="{active:isFlag,aaa:true}">按钮button>你也可以传入一个数组:h2:class="['aaa','bbb']">HelloVueh2>h2:class="[className1,className2]">HelloVueh2>甚至是对象和数组混合使用:h2:class="['aaa',{active:isFlag}]">HelloVueh2>而在React中就相对繁琐了,React在JSX给了我们开发者足够多的灵
从ReactRouterV3过渡到V4后,我再也无法使ReactTransition组低级API工作。React路由器的文档显示了与CSS动画相关的高级API的示例,这些示例与低水平的JS风味不起作用。任何人都设法或知道让这个工作?看答案已经一个月了,所以我想您找到了自己的出路,但可能会对他人有所帮助。我创建了这个:https://www.npmjs.com/package/reeact-router-v4-transition在我遇到同样的问题之后。它在开关组件中提供了一种过渡组。从将开关更改为TransitionSwitch的Appart,它不需要大幅度更改。我将在接下来的几天(可能是星期
是在React-Router(1.0.0-rc)url参数中的路由之间传递数据的唯一方法吗?我有一个组件A,它使用Historymixin,并且有一个事件处理程序,该事件处理程序发出服务器请求,然后调用that.history.pushState(null,'/B');以过渡到路由B由组件B处理。现在,我想将服务器返回的一些数据作为Prop(例如“登录成功”)传递给组件B,或者以某种方式影响B的状态,但我找不到任何说明这是可能的。有什么办法可以做到这一点,还是我需要将其作为url参数传递? 最佳答案 你有两个选择:将数据作为查询参数
我最近开始使用React,我遇到了输入验证问题。例如,它只是通过指令在另一个框架中作为Angular.js实现。经过一番研究,我发现newforms库,看起来像是当前开箱即用的最佳解决方案。但它非常重,不确定当前是否支持它(最后一次更新是7个月前)。另一种方法是将事件从父表单发送到其子输入,并在每个子输入上调用验证方法。但我找不到每个人都试图发明自己的东西的最佳实践,因此你需要自己写一些东西。表单验证的最佳解决方案是什么?React架构/框架(Flux/Redux)是否提供任何解决方案?谢谢, 最佳答案 我最近在React中使用了一
我正在创建一个网络应用程序,该应用程序将根据用户点击的城市对OpenWeatherAPI进行AJAX调用以获取城市的天气数据。我的前端使用React,后端使用Node.js/Express-但我无法正确设置如何根据用户的点击进行API调用。如何重构我的代码以使其基于点击?这是我目前所拥有的(JSBIN:http://bit.ly/1WedsL2)——目前硬编码为“London”:vardata=[{name:"London"},{name:"Tokyo"},{name:"NYC"}];varMusicBox=React.createClass({render:function(){re
调试React网站时,我可以使用ReactDeveloperTools查看组件层次结构:我如何在ReactNative中做同样的事情?rageshake菜单包含一个“检查器”,但它似乎只能让我通过点击它来检查单个元素-我看不到任何浏览完整组件层次结构的方法。 最佳答案 不幸的是,从react-native0.12版本开始,Devtools的“React”选项卡不再起作用。这是aknownissue.有一个quiteactivediscussiononGithub已经开放了一段时间,但还没有解决方案。更新Devtools“React”
如何在ReactJS中禁用Canvas中的右键单击。这是我尝试过但仍然无效的方法:letCanvas={e.preventDefault();returnfalse;}}height={500}width={500}ref="canvas"/>;浏览器控制台中也会显示警告。Warning:Returningfalsefromaneventhandlerisdeprecatedandwillbeignoredinafuturerelease.Instead,manuallycalle.stopPropagation()ore.preventDefault(),asappropriate.
我正在学习React,我尝试创建一些路由,我的入口点上有这段代码:importReactfrom'react';importReactDOMfrom'react-dom';import{Router,Route,IndexRoute,Link,IndexLink,browserHistory}from'react-router';importAppfrom'./app/Components/AppComponent';importSupervisoryReportfrom'./app/Components/SupervisoryReportComponent';importTopmen