从零初叶搭建3个react项目开发,native项目中从零早先使用redux

By admin in 4858美高梅 on 2019年3月25日

  redux作为react的场合状态管理工科具,是老大注重的一有个别,然则它在就学起来比较不方便。它的写法一共分成三局地,而且她不像其余的东西一律能够写一步,在页面上查看一下。它必须四个部分全部形成之后,才能查看效果,所以redux在报错的时候也是特其他厌烦的,不好查找具体是在哪一步写错了内容。

正文重如若以自小编的另一篇小说的思维进程来操作,希望大家使用后得以记住整个经过,从而活学活用,使用到祥和的种类中.

开卷了官网的事物,看的成套人都懵逼了,然后找了任何的一些稿子,看的快睡着的时候突然看出来了点意思,遂,写此来记录

从零开头搭建叁个react项目支付,搭建react项目支付

正文介绍了从零初叶搭建一个react项目花费,分享给大家,具体如下:

1、npm init 生成 package.json 文件.

贰 、安装种种急需的依赖性:

npm install
 –save react – 安装React.

npm install
 –save react-dom 安装React Dom,这几个包是用来拍卖virtual
DOM。那里提一下用React Native的话,那里正是设置react-native。

npm install
 –save-dev webpack – 安装Webpack, 现在最流行的模块打包工具.

npm install
 –save-dev webpack-dev-server –
webpack官网出的2个小型express服务器,首要特征是支撑热加载.

npm install
 –save-dev babel-core – 安装Babel,
能够把ES6变换为ES5,注意Babel最新的V6版本分为babel-cli和babel-core三个模块,那里只须要用babel-cor即可。

设置任何的babel依赖(babel真心是贰个一家子桶,具体的介绍去官网看吧..作者背后再下结论,那里反正全装上正是了):
npm install
 –save babel-polyfill – Babel includes a polyfill that includes a
custom regenerator runtime and core.js. This will emulate a full ES6
environment

npm install
 –save-dev babel-loader – webpack中须要使用的loader.

npm install
 –save babel-runtime – Babel transform runtime 插件的注重.

npm install
 –save-dev babel-plugin-transform-runtime – Externalise references to
helpers and builtins, automatically polyfilling your code without
polluting globals.

npm install
 –save-dev babel-preset-es2015 – Babel preset for all es2015 plugins.

npm install
 –save-dev babel-preset-react – Strip flow types and transform JSX into
createElement calls.

npm install
 –save-dev babel-preset-stage-2 – All you need to use stage 2 (and
greater) plugins (experimental javascript).

③ 、打开 package.json 然后添加下面包车型大巴scripts:

"scripts": {
 "start": "webpack-dev-server --hot --inline --colors --content-base ./build",
 "build": "webpack --progress --colors"
}

命令行输入 npm start 将要运转webpack dev server.

命令行输入 npm build 将会进展生产环境打包.

4、启动webpack

Webpack是大家的包装工具,在大家的开销条件中现实很要紧的功效,具有许多要命便利的个性,特别是热加载hot
reloading. webpack.config.js 是之类所示的webpack的布署文件.
随着app的频频变化,配置文件也会没完没了的翻新,那里我们就用暗中认可的webpack.config.js来命名那几个布局文件,要是你用其他名字比如webpack.config.prod.js那么地方的脚本build就要求相应的改动钦赐相应的布局文件名字:”build”: “webpack
webpack.config.prod.js –progress –colors”

var webpack = require('webpack');
module.exports = {
 entry: './src/app.js',
 output: {
  path: __dirname + '/build',
  filename: "bundle.js"
 },
 module: {
  rules: [{
   test: /\.js$/,
   exclude: /node_modules/,
   loader: 'babel-loader',
   query: {
    plugins: ['transform-runtime'],
    presets: ['es2015', 'react', 'stage-2']
   }
  }, {
   test: /\.css$/,
   loader: "style-loader!css-loader"
  }]
 }
};

OK,大家项指标宗旨配置终于形成了,是时候初叶写Reac代码了.

React 基础 – 建立你的首先个Component

在上边的品种的着力配备基础上,大家开始书写React的第二个零件来领悟React的写法与组件思想。

首先大家在类型根目录中新建三个 index.html 文件。 在这一个基础工程中,
大家运用bootstrap的样式,直接引入3个cdn即可. 然后添加二个html标签
<div id=”app”></div>,大家的app就会注入到这些div中。
最后再引入 <script
src=”bundle.js”></script>,那是最终打包生成的js代码。

以下是全体的代码:

 <!DOCTYPE html>
 <html lang="en">
 <head>
 <meta charset="UTF-8">
 <title>Document</title>
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="external nofollow" >
 </head>
 <body>
 <div id="app"></div>
 <script src="bundle.js"></script>
 </body>
 </html>

树立贰个新的文本夹 src. 大家app的绝抢先四分之二代码都将身处这么些文件夹里面。在
src中建立 app.js,作为React App的根组件,
别的具有的零件都会注入到这几个跟组件中。

第壹大家须求导入react,今后都早就用ES6的语法, import React from
‘react’; , 然后大家要引入react-dom.
那其间有react中最要紧的3个虚拟dom的概念.引入代码:import ReactDOM

from 'react-dom';

前日亟需引入的信赖都曾经终止我们得以写第②个零件了:

 class App extends React.Component {
 render(){ // Every react component has a render method.
  return( // Every render method returns jsx. Jsx looks like HTML, but it's actually javascript and functions a lot like xml, with self closing tags requiring the `/` within the tag in order to work propperly
  <div>
   Hello World
  </div>
  );
 }
 }

注意那里”Hello World”写在 div中. 全体的jsx代码都亟需写在三个父div中.

最终大家须求把大家写好的零件render给Dom,那里就供给用到 ReactDOM.render
方法.

在 App.js 的上面添加: ReactDOM.render(<App />,
document.getElementById(‘app’));

率先个参数正是大家App的根组件, 写作<App />的格局.
第三个参数就是我们的APP将要重要的DOM成分.
在那些项目中,正是大家在index中写的id为app的 div标签。

Ok,我们的APP结构已经出来了,经典的hello
world已经落实。立刻大家就在这一个基础上再落到实处经典的todo
app。大概的原型就有3个输入框用来输入代办事项然后添加到事件列表中。事件列表中各个代办事项被点击就会标澳优(Ausnutria Hyproca)条删除线表示完结,点击后边的去除按钮则会将其从列表中剔除。通过形成那么些APP的进程你将学会八个完好的react
app的拥有的基本营造块。

生命周期方法和三种样式的机件营造

大家从部分小的模块开头起步.3个组件component就是二个react app的构件块.
有三种格局的零部件: 类组件(Class)和函数型组件(Functional).
在这一个类别中,那三种格局的零件大家都会利用,
并且使用生命周期的钩,同时也会利用state和props多少个react中最首要的性情。

第③在 src文件夹中新建components 文件夹,你的公文结构正是那样
~/src/components。

接下来在components中新建文件 ToDoApp.js。
对于有着的react组件我们都要求在头顶引入reactimport React from ‘react’;。

上面大家写一个类组件. 全部的class 组件有1个render方法用来回到jsx。

ToDoApp的class就好像下所示:

 class ToDoApp extends React.Component {
  render() {
   return (
    <div>To Do App</div>
   );
  }
 }

为了将以此组件注入到大家的APP中, 首先大家要求输出它。
在那一个组件代码底部添加 export default ToDoApp;。

下一场在app.js顶部咱们添加 import ToDoApp from ‘.components/ToDoApp’;
导入组件用来替代 Hello World 。 render中替换为新的jsx代码 <ToDoApp
/>半关闭类型的标签即可。

下一场在浏览器中您就能够看看”To Do App” 代替了原先的 “Hello
World”!那样我们就马到成功了将率先个头组件嵌入到根组件之中了,那正是营造react
app的正常格局。下边继续全面大家的零部件。

回来到ToDoApp
中来创设我们的率先个代办事项列表。首先大家利用bootstrap来创设相比便于且赏心悦目。
用上面包车型大巴jsx替换当前render方法中 return 中的jsx:

<div className="row">
<div className="col-md-10 col-md-offset-1">
 <div className="panel panel-default">
  <div className="panel-body">
   <h1>My To Do App</h1>
   <hr/>
   List goes here.
  </div>
 </div>
</div>
</div>

今天开拓浏览器, 你将会看出一个标题 “My To Do App”
上边跟随2个bootstrap的panel组件里面写有 “List Goes
Here”,我们将在那么些地方创设列表。
那么大家什么样将数据存款和储蓄在大家的列表中吗? 答案便是利用 state.
每种类组件都有 state 属性,能够由此 this.state在组件任何职分别获得取并且用
this.setState({
 key: “value”
})那种措施来更新境况。不过唯有供给我们相比少使用state,那里权且先选用作为明白,早先时期会使用redux来管理情状。

在ToDoApp中大家能够动用过多生命周期方法的钩子,
当中三个正是component威尔Mount。
那一个方法的实践是在页面加载并且render方法从前。能够在个中赢得列表数据,在大家的APP中央直机关接用贰个虚构的数组提供。(值得注意的是component威尔Mount会唤起不少小标题,因而实际项目中尽量不要选取,而是应当用componentDidMount)。

在 ToDoApp中 render 方法以前拉长:

  componentWillMount(){ // run before the render method
   this.setState({ // add an array of strings to state.
    list: ['thing1', 'thing2', 'thing3']
   })
  };

后天大家取得了贰个虚构列表,供给珍视注意的就是react正视于state和props,唯有当state和props改变的时候react组件才会刷新。

近来我们添加列表到这些view里,那里不是间接省略的在内部修改jsx,而是更创设二个新的组件来营造列表,此次大家学习运用函数型组件,需求专注的是函数型组件没有生命周期方法和state属性,它独自是一个回去jsx的函数,并且参数是props。

那就是说props到底是什么样吗?props是从父组件传递进子组件的数额的名字,那是三个很要紧的概念,也是react
app数据传递的最特异与最推荐的法门。平常大家将数据保持在app的下面组件,通过组件让多少流下来保障APP的规范运维。这么些多少和props的一部分处理或者会影响APP的运作,不过假若你根据那么些课程的施行流程来做,这一个影响都会极小。

再新建三个components文件夹并在其间新建叁个List.js作为我们要创制的函数型组件。用const来新建三个函数,参数名字写作props。

函数格局如下所示:

 const List = (props) => { // we're using an arrow function and const variable type, a ES6 features

  return (
   <div>
    I'm a list!!!
   </div>
  )
 };

 export default List;

在 ToDoApp.js引入 List用List 组件替换 List goes here.,写法为 <List
/>.未来在浏览器中就能够看来”I’m a list!!!”

近期我们来把那些变成实际的列表,首先就要求通过props传递数据,大家把这些从state中拿走的数据list通过命名为listItems的props传递,写作:
<List listItems={this.state.list} /> ,未来 List
已经因而props获取了 ToDoApp中的数据。

从零初叶搭建3个react项目开发,native项目中从零早先使用redux。然后在 List 组件中大家必要render3个列表,先用上面包车型客车jsx代码代替:

<div>
 <ul>
  {
   list // this is a variable we'll define next
  }
 </ul>
</div>

注意那些大括号,js能够在那中间实践并将赶回添加到view里。首先大家定义贰个列表变量:

const list = props.listItems.map((el, i)=>(
 // All where doing here is getting the items listItems prop
 // (which is stored in the state of the parent component)
 // which is an array, and we're running the .map method
 // which returns a new array of list items. The key attribute is
 // required, and must be unique.
 <li key={i}><h2>el</h2></li>
));

一体化的零件如下:

import React from 'react';

const List = (props) => {

 const list = props.listItems.map((el, i)=>(
  <li key={i}><h2>el</h2></li>
 ));

 return (
  <div>
   <ul>
    {
     list
    }
   </ul>
  </div>
 )
};

export default List;

近日开拓浏览器就能够看出一列列表了。接下来正是给我们的类型出席作用了,包涵添加新的事项,标注事项到位和删除列表中事项。

给APP添加效果

1.函数型组件

率先我们须要丰裕多少个input成分以便可以输入代办事项。由此大家在components文件夹中新建一个Input.js,然后在个中创制并出口3个称呼Input的函数型组件。

把下部的jsx代码粘贴到你的函数型组件return之中:

<form>
 <div
  className="form-group">
  <label
   htmlFor="listInput">
   Email address
  </label>
  <input
   type="text"
   className="form-control"
   id="listItemInput"
   placeholder="Add new todo"
  />
  <button
   className="btn btn-primary">
   Add Item
  </button>
 </div>
</form>

2. Input

于今大家的jsx没有做此外特殊的作业,仅仅是1当中坚的html视图,然则我们先测试一下把其导入到ToDoApp.js,方式就是<Input/>。

此刻会发觉一个输入框和按钮的视图,这么些组件的静态视图已经写好了,下边就须要添加效果了。

3. Props

首先大家要求做的是什么样收获输入框的值,因为那一个输入框的值需求在别的零件中获得,所以我们并不想要在Input组件中来拍卖那几个数量存款和储蓄。事实上,在子组件中贮存数据在其余时候都以不引进的,大家应当将数据存款和储蓄在app的上方组件并且经过props传递下去。

另贰个急需记住的是即是大家当前把多少存款和储蓄在了上层的 ToDoApp
组件,中期仍旧会用redux来取代来拍卖整个app的数据。那里先仅仅使用react的state来达成。

ok,大家在ToDoApp的
component威尔Mount的setState中新增3个newToDo属性用来存款和储蓄输入框的值。

 componentWillMount(){
  this.setState({
   list: ['thing1', 'thing2', 'thing3'],
   newToDo: 'test'
  })
 };

一致的就能够透过在<Input />上经过props传递下去。

4. 解构(Destructuring)

在Input.js中大家因此参数props能够博得上级组件传递下去的值,
不过还能用ES6的新特点解构来作为参数,那样看起来越发酷!

把Input组件的props参数修改为({
 value
})那样的参数方式,那样能够把props这一个指标参数解构为1个个键值对。直接看个小例子来就很明亮了:

var props = {
 name: 'hector',
 age: 21
}


function log(props){
 console.log(props.name);
 console.log(props.age);
}

log(props);

is the same as this:

let props = {
 name: 'hector',
 age: 21
}

log = ({name, age}) => {
 console.log(name);
 console.log(age);
}

log(props);

5. setState

地点的newToDo仅仅是添加了3个state用来囤积输入框的值,给定三个值,输入框就会议及展览示,明显还不是大家要的效益,大家必要做的是依照输入框的值的转移来动态改变那么些state。

为了促成那几个作用,大家须要再添加三个onChange方法一致应用props传进Input组件:
onChange={onChange}, 然后解构参数便是({ onChange, value })。

然后在 ToDoApp.js的component威尔Mount 添加三个新的章程
onInputChange。那些法子有三个参数event, 它将要捕获用户在输入框输入的值。

onInputChange = (event) => {
 this.setState({ newToDo: event.target.value}); // updates state to new value when user changes the input value
};

6. 添加新列表事项

以后亟需向列表中添加新的事项,也正是在付给后能把输入框的值存款和储蓄并出示到列表中。我们需求再新建三个onInputSubmit的措施,参数同样是event,函数体内率先要求写
event.preventDefault(),然后用 setState
方法把新事项添加到列表数组中,然而,一定要小心我们的state应该是immutable的,那是react中务必遵照的一个准则,那样才能担保相比性与可靠性。

为了贯彻那几个功能, 要求用到this.setState 回调函数,参数为previousState:

this.setState((previousState)=>({
 list: previousState.list.push(previousState.newToDo)
}))

正如自己上面的描述,最开端写state的时候很两人都会犯那样的一无可取,直接用push那样的办法,修改了state,那样就不算immutable的,大家自然要确定保障绝不间接改动原state。

那边又有什么不可用到ES6中的新特色了,增加操作符,它通过遍历旧数组再次来到四个新数组,使旧的数组保持原样,那样我们就把事项添加到列表数组末尾:

this.setState((previousState)=>({
 list: [...previousState.list, previousState.newToDo ], // the spread opperator is called by using the ... preceding the array
}));

在交付添加新事项的还要,供给将newToDo重置为”:

this.setState((previousState)=>({
 list: [...previousState.list, previousState.newToDo ],
 newToDo: ''
}));

7. 划掉事项

是时候增进划掉事项的服从了。为了达成那个意义需求加上3个新的习性用来标注是不是要求划掉,由此供给改变原先的数组为1个目的数组,每三个事项都以多个对象,1个key为item表示原本的事项内容,多个key为done用布尔值来表示是还是不是划掉。
然后先把原先的onInputSubmit方法修改,同样要留意immutable,使用扩张操作符如下:

onInputSubmit = (event) => {
 event.preventDefault();
 this.setState((previousState)=>({
  list: [...previousState.list, {item: previousState.newToDo, done: false }], // notice the change here
  newToDo: ''
 }));
};

质量done添加实现后就要求新增多少个方法当点击事项时候来改变这些值:

onListItemClick = (i) => { // takes the index of the element to be updated
 this.setState((previousState)=>({
  list: [
   ...previousState.list.slice(0, i), // slice returns a new array without modifying the existing array. Takes everything up to, but not including, the index passed in.
   Object.assign({}, previousState.list[i], {done: !previousState.list[i].done}), // Object.assign is a new ES6 feature that creates a new object based on the first param (in this case an empty object). Other objects can be passed in and will be added to the first object without being modified.
   ...previousState.list.slice(i+1) // takes everything after the index passed in and adds it to the array.
  ]
 }))
};

然后把那个法子通过props传递给List
组件,那里就没有采取解构参数字传送递,用来和Input的做比较。因为那几个函数须要贰个参数就是当下列表的行列号,可是毫无疑问不可能一贯call这么些函数不然会报错,由此利用bind方法,出入i参数:

onClick={props.onClick.bind(null, i)}

自然还有另一种艺术:

onClick={() => props.onClick(i)}

接下来在事项内容的span标签上添加 onClick
方法,改变方今事项的done值后,在通过判断此布尔值来进行体制的改动添加可能划掉删除线。

8. 刨除事项

末段大家在丰硕删除事项的意义,这一个和划掉事项非凡相似,大家只需求新增1个删减按钮,然后再疯长多少个措施修改列表,具体代码如下:

<button
 className="btn btn-danger pull-right"
 >
 x
</button>

deleteListItem = (i) => {
 this.setState((previousState)=>({ // using previous state again
  list: [
   ...previousState.list.slice(0, i), // again with the slice method
   ...previousState.list.slice(i+1) // the only diffence here is we're leaving out the clicked element
  ]
 }))
};

把deleteListItem
方法传递到列表组件中然后在剔除按钮上绑定即可,仿照上3个本人写一下就好。

现行反革命大家有贰个全部意义的APP了,是否觉得很cool,那一个正是不要redux时候的形状了,然而你会发觉当状态越来越复杂时候很麻烦,因而我们下边就要介绍redux来治本状态了。

搬迁到redux的备选工作

以至于近年来大家曾经学会如何用webpack和babel搭建react应用,创设类组件和函数型组件并拍卖state,添加效应。但是那只是骨干满意3个小型应用的须求,随着app的滋长,处理多少和作为会愈来愈难于,那正是要引入redux的须要性。

那就是说redux如何处理数量?首先,redux给你的app3个纯粹的state对象,与flux等根据view来划分为多少个state对象正好相反。你恐怕会有疑点,三个十足的对象来拍卖二个复杂的app岂不是相当复杂?redux接纳的形式是把数据处理分为reducer
 functions、action creators和actions然后组成在一道工作流线型的拍卖多少。

1. 率先安装必须的依赖

先是安装 redux and react-redux

npm install --save redux
npm install --save react-redux

接下来安装 redux middleware,那里就先安装
redux-logger,它的法力是支持大家开发。

npm install --save redux-logger

还有一些常用的中间件,比如 redux-thunk and redux-promise,
然则在大家的那些类型中方今先不须要,能够自行去github驾驭。

2. 构建

使用redux创设react应用一般都有叁个标准的沙盘,或许两样模板格局上有差异,不过思考都以同一的,上面就先依据一种文件结构来创设。

第①大家在src中新建一个文书夹redux,然后在里头新建三个文本configureStore.js,添加以下代码:

import { createStore, applyMiddleware, combineReducers } from 'redux';
import createLogger from 'redux-logger';

createStore 是由redux提供的用来开始化store的函数,
applyMiddleware是用来添加大家须要的中间件的。

combineReducers 用来把八个reducers合并为一个单纯实体。

createLogger
就是我们那边唯一采纳的叁当中间件,能够console出每二个action后数据的详细处理进程,给调节和测试带来了相当的大便宜。

然后添加上面代码:

const loggerMiddleware = createLogger(); // initialize logger

const createStoreWithMiddleware = applyMiddleware( loggerMiddleware)(createStore); // apply logger to redux

那里一时并未完毕,须要前面包车型大巴模块写完了再导入到那里延续来完结。

3. 模块Modules

在 src/redux/ 新建贰个文本夹
modules。在那一个文件夹中大家将存放全数的reducers,action creators和constants。这里我们采用的redux组织结构叫做ducks,思想正是把相关的reducers,action creators和constants都坐落三个独立的文书中,而不是分开放在八个公文中,那样修改1个功效时候一贯在一个文件中期维修改就足以。

在 modules 文件中新建
‘toDoApp.js’,注意那里的命名是基于容器组件的名字来定名,这一个也是正规,不难管理代码。

最近我们得以起来创立initial state和
reducer function,这实际上格外简单,state正是一个js对象,reducer便是js的switch语句:

const initialState = {}; //The initial state of this reducer (will be combined with the states of other reducers as your app grows)

export default function reducer(state = initialState, action){ // a function that has two parameters, state (which is initialized as our initialState obj), and action, which we'll cover soon.
 switch (action.type){
 default:
  return state;
 }
}

4. 完善Store

未来大家早已完结了第③个reducer,能够将其添加到 configureStore.js
中去了, 导入: import toDoApp from ‘./modules/toDoApp’;

接下来用combineReducers 来组成当前的reducer,因为前景会有越多的模块参预。

const reducer = combineReducers({
 toDoApp
});

最后在底部插足上边完整的代码:

const configureStore = (initialState) => createStoreWithMiddleware(reducer, initialState);
export default configureStore;
Cool. We're done here.

5. Connect

当今我们曾经有了一个reducer,那么怎么和app建立联系呢?这必要两步工作。

日前已经讲过类组件和函数型组件,有时候也足以称为smart components和dumb
components,那里大家新增一种容器组件,顾名思义,那种组件就是作为叁个容器用来给组件提供actions和state。

下边来创制第一个容器组件,首先在 /src/
下增产三个文件夹containers,然后再其下部新建一个文toDoAppContainer.js。

在文件顶部首开首入 connect 用来将容器和零部件联系在一起,

import { connect } from 'react-redux';
import ToDoApp from '../components/ToDoApp.js'

connect 那一个函数被调用两遍, 第①遍是三个回调函数: mapStateToProps and
mapDispatchToProps。
第三遍是把state和dispatch传入组件的时候。那里的dispatch又是什么样呢?

当大家须求在redux中发生一些行为时候,就须求调用dispatch函数字传送递三个action然后调用reducer这一套流程。因为我们还没有编写制定具体的行为,这里就权且间和空间白,后边再补,代码方式如下:

function mapStateToProps(state) {
 return {
  toDoApp: state.toDoApp // gives our component access to state through props.toDoApp
 }
}

function mapDispatchToProps(dispatch) {
 return {}; // here we'll soon be mapping actions to props
}

接下来在底部添加:

export default connect(
 mapStateToProps,
 mapDispatchToProps
)(ToDoApp);

1、Provider

redux的中坚工作已经成功,最终一步就是重回到app.js 文件,
首先我们不再必要导入 ToDoApp
组件,而是用容器组件ToDoAppContainer来替代,然后须求导入 configureStore
函数和 Provider,在头顶添加代码:

import { Provider } from 'react-redux';
import ToDoAppContainer from './containers/ToDoAppContainer';
import configureStore from './redux/configureStore';

configureStore is the function we created that takes our combined
reducers and our redux middleware and mashes them all together. Let’s
intialize that with the following line:

const store = configureStore();

接下来return的jsx中一律须要把ToDoApp 改为
ToDoAppContainer,然后须求用Provider
组件将其包装,它的功能正是将总体app的state传递给它所包裹的容器,从而使容器组件能够赢得那一个state。

<Provider store={store}> // we pass the store through to Provider with props
 <ToDoAppContainer />
</Provider>

当今全方位redux的主干结构已经搭建起来,下一步就足以把整个行为逻辑代码补充进去就能够了。

Redux Actions 和 Reducers

搭建起redux的大旨结构后,就能够填充redux的因素了,简单的说大家只需求牢记多少个概念,
Types, Actions, Action Creators, and
Reducers。然后把这几个因素用ducks的文件协会结构组织起来就足以了。

Ducks

规则

在module中我们必要依据下边包车型大巴代码风格和命超格局:

  1. 须用 export default 输有名为 reducer()的函数
  2. 须用 export 输出 函数格局的action creators
  3. 须用 npm-module-or-app/reducer/ACTION_TYPE的命名情势来命名action
    types,因为到早先时期很多reducer,不一样的人协同工作难免会现身命名重复,那样子加上app和模块的前缀的话就不会现身命名争辨的题材。
  4. 须用小写的蛇形格局UPPEKoleos_SNAKE_CASE来命名action types。

Types

以此types正是地方第3条中供给根据ducks的标准命名的常量名字,将其写在文书的顶部,当action
触发时候会传送给reducer,reducer的switch语句会依照这些type来拓展相应的多少处理。

const ADD_ITEM = 'my-app/toDoApp/ADD_ITEM';
const DELETE_ITEM = 'my-app/toDoApp/DELETE_ITEM';

Actions

Actions
就是三个足足含有type的简练的js对象,同时能够分包数据以便传递给reducer。当用户在页面上接触了某种行为,三个aciton
creator将会发送aciton给reducer做多少处理。

action示例如下:

{ type: ADD_ITEM, item: 'Adding this item' }
{ type: DELETE_ITEM, index: 1 }
{ type: POP_ITEM }

Action Creators

Action creators
是创办acitons并传递给reducer的函数,它平时重返八个action对象,有时候借用thunk那样的中间件也足以回去dispatch八个actions,在我们的app中为了简化一时半刻不关乎那个格局。

function addItem(item){
 return {
  type: ADD_ITEM,
  item // this is new ES6 shorthand for when the key is the same as a variable or perameter within the scope of the object. It's the same as item: item
 }
}

Reducers

reducer是唯一能够触碰store的成分,开首值为initialState,情势上正是1个大概的switch语句,不过注意不能直接改动state,因为state是immutable。也正是说大家不可能一贯动用.pop
or .push这一个方法操作数组。

上边是出现说法代码:

const initialState = {
 list: []
};

export default function reducer(state = initialState, action){
 switch (action.type){
 case ADD_ITEM:
  return Object.assign(
   {},
   state,
   { list: [...state.list, action.item]} // here we see object.assign again, and we're returning a new state built from the old state without directly manipulating it
  )
 default:
  return state;
 }
}

概念已经介绍完结,上面开始将原来的成效逻辑用redux重写。

1. Initial state

先是大家在 src/redux/modules/toDoApp中扬言initialState。

const initialState = {
 list: [{item: 'test', done: false}] // just added this to test that state is being passed down propperly,
 newToDo: ''
};

export default function reducer(state = initialState, action){
 switch (action.type){
 default:
  return state;
 }
}

近日在 ToDoApp.js的 render() 方法中return此前添加console.log(this.props)
会打字与印刷出上边包车型大巴对象:

toDoApp: Object
 list: Array[1]
  0: "test"
  length: 1
  __proto__: Array[0]
 __proto__: Object
__proto__: Object

测试通过,大家就足以传递那几个多少给子组件了,那里就能够把本来List组件的
listItems prop和Input的value prop替换掉了。

<List
 onClick={this.onListItemClick}
 listItems={this.props.toDoApp.list}
 deleteListItem={this.deleteListItem}
/>
<Input
 value={this.props.toDoApp.newToDo}
 onChange={this.onInputChange}
 onSubmit={this.onInputSubmit}
/>

此处只是交替掉了数量,上面还亟需把action也交替。

3. Input action

本条历程就是把大家本来在ToDoApp 组件的行为逻辑全体搬迁到redux文件夹下的
toDoApp module中去。

const INPUT_CHANGED = 'INPUT_CHANGED';

export function inputChange(newToDo){
 return {
  type: INPUT_CHANGED,
  newToDo
 }
}

接下来在reducer的switch中新增如下处理:

case INPUT_CHANGED:
  return Object.assign(
   {},
   state,
   {newToDo: action.value}
  );

在 toDoAppContainer.js 的 mapDispatchToProps
函数就供给回到相应的action,首开始入 inputChange, 具体代码如下:

import { connect } from 'react-redux';
import ToDoApp from '../components/ToDoApp.js'
import {
 inputChange
} from '../redux/modules/toDoApp'; // we added this

function mapStateToProps(state) {
 return {
  toDoApp: state.toDoApp // gives our component access to state through props.toDoApp
 }
}

function mapDispatchToProps(dispatch) {
 return {
  inputChange: (value) => dispatch(inputChange(value)) // we added this
 };
}

export default connect(
 mapStateToProps,
 mapDispatchToProps
)(ToDoApp);

那般state和action都传送给了toDoApp然后再通过props传递给子组件就足以应用了,具体都得以看项目最后代码。

4. 其他 actions

别的acitons的代码情势跟上边包车型地铁骨干均等,那里不在赘述。

总结

到那边多少个应用webpack打包的react+redux(ducks)的主导使用模型就出去了,即便简易然则是我们开始展览更复杂项指标基础,并且有了这么些基础前边的行程将会顺手多了,一起进入react的我们庭吧。

上述便是本文的全体内容,希望对大家的求学抱有支持,也盼望大家多多帮助帮客之家。

本文介绍了从零伊始搭建2个react项目费用,分享给我们,具体如下: 壹 、npm
init 生成…

  上面简单来讲二个本身对它的片段摸底和平运动用,给大家提供一些参考

参考作品:react-native中应用redux的规律分析及demo

1.先是需求设置 redux,react-redux,react-thunk(中间件),

  好的,使用redux最早先的一步就是设置

demo地址:github.com/NextChampion/react-native-redux-navigation-example

npm install redux –save 

npm install react-redux –save 

npm install react-thunk –save 

  npm i –save redux和npm i
–save react-redux

效果图

应用的是新版的奇骏N,先要理清楚执行的顺序跟思路再展开写。

  安装到位之后,大家去修改index.js文件的剧情,先河入Provider

4858美高梅 1

例如贰个登陆的操作

import {Provider} from 'react-redux'

效果图

1.未输入用户名,密码的时候,按钮是不可点击气象,当大家输入的时候状态要变为 登陆

  下一步

demo简单介绍:

功效:登录页中式点心击登录,跳转到主页,主页内涵盖几个咱们都很纯熟的counter组件.能够落成简单的加减数操作;

2.输入的时候我们要运用redux中的dispatch来触发,然后action经受到发送的始末来开始展览

 1 class Index extends React.Component{
 2     render() {
 3         return (
 4             <React.Fragment>
 5                 <Provider>
 6                     <App/>
 7                 </Provider>
 8             </React.Fragment>
 9         );
10     }
11 }
12 
13 ReactDOM.render(<Index />, document.getElementById('root'));

demo逻辑:

登录:

点击登录时,组件的点击方法会发送新闻到action内,

action将该消息预处理,即区分一下type,然后重临给store,

store将分好类的音讯,分配到reducer中处理state.

reducer接收到含有type的新闻之后,找到呼应的拍卖措施,生成新的state重返给store,

store控制页面渲染,跳转到主页;

加减:

点击加号,组件将该点击方法发送到action内,

action预处理该新闻,区分是加/减,钦命type后,重临信息给store;

store收到预处理后的新闻后,将该音讯发送给reducer;

reducer收到store发过来的信息,根据音信内的type处理多少,真正开始展览加/减进程,并且将新的state重回给store;

4858美高梅 ,store收到reduder发过来的新state,控制页面渲染,即页面中数字的更动;

判定(逻辑的处理)给出3个判定的结论,有了结论那么就必要实行实际的操作

今昔页面日常是能够展现出来的,不过在支配台内会有七个报错,这一个我们先不用管

demo特点:

1.区分登录和加减逻辑,并且将区别的state对应分裂的组装部分

报到相关的state只有loginPage可用,加减相关的state唯有主页面可用;

2.页面切换使用react-navigation控制;

3.该demo大家能够拿去修改部分代码,直接类比内部redux的逻辑达成进度,开发自个儿的品种;

下边开始详细讲解整个demo的贯彻进度

1.新建项目

4858美高梅 2

react-native init CountersDemo

2.安装redux相关文件

4858美高梅 3

npm install –save redux

npm install –save react-redux

npm install –save react-navigation

npm install –save redux-thunk

3.确立项目里面文件夹

4858美高梅 4

4858美高梅 5

4.redux相关代码实现进度

1)新建src文件夹存放全部js文件.

2)新建constants,actions,reducers,store,container,pages文件夹

3)(设定类型type)
constans文件夹内新建文件loginType,用来划分登录进程中的事件体系

4858美高梅 6

export const LOGIN_IN_DOING = ‘LOGIN_IN_DOING’; //正在登陆

export const LOGIN_IN_DONE = ‘LOGIN_IN_DONE’; // 登陆完毕

export const LOGIN_IN_ERROR = ‘LOGIN_IN_E本田UR-VROPAJERO’; // 登陆出错

4.(设定预处理音信进度)actions文件夹内,新建loginAction文件,用来给预处理音讯区分各种事件的项目

4858美高梅 7

‘use strict’;

import * as types from ‘../constants/loginTypes’;//
导入事件类型,用来做分配给各类事件

// 模拟用户消息

let user = {

name: ‘zhangsan’,

age: 24,

}

// 访问登录接口
依照再次来到结果来划分action属于哪个type,然后回到对象,给reducer处理

export function login() {

console.log(‘登录方法’);

return dispatch => {

dispatch(isLogining()); // 正在推行登录请求

// 模拟用户登录

let result = fetch(”)

.then((res)=>{

dispatch(loginSuccess(true,user)); // 登录请求完结

}).catch((e)=>{

dispatch(loginError(false)); // 登录请求出错

})

}

}

function isLogining() {

return {

type: types.LOGIN_IN_DOING

}

}

function loginSuccess(isSuccess, user) {

console.log(‘success’);

return {

type: types.LOGIN_IN_DONE,

user: user,

}

}

function loginError(isSuccess) {

console.log(‘error’);

return {

type: types.LOGIN_IN_ERROR,

}

}

5.(设定新闻的切实处理进程)reducers文件夹内新建loginReducer文件,用来拍卖登录进程中的state变化

4858美高梅 8

‘use strict’;

import * as types from ‘../constants/loginTypes’; //
导入事件连串,用来做事件类其余判定

// 早先状态

const initialState = {

status: ‘点击登录’,

isSuccess: false,

user: null,

}

// 分化品类的事件选取switch对应处理进程

export default function loginIn(state=initialState, action) {

switch (action.type) {

case types.LOGIN_IN_DOING:

return {

…state,

status: ‘正在登陆’,

isSuccess: false,

user: null,

}

break;

case types.LOGIN_IN_DONE:

return {

…state,

status: ‘登陆成功’,

isSuccess: true,

user: action.user,

}

break;

case types.LOGIN_IN_ERROR:

return {

…state,

status: ‘登录出错’,

isSuccess: true,

user: null,

}

break;

default:

return state;

}

}

6).项目内也许并不是唯有三个redux操作逻辑,今后给拥有的reducer建立四个联结的进口

reducers文件夹内新建index.js文件,作为联合入口;

(由于本篇文章是demo写好后整治的,所以未来那里不应有有counterReducer,大家在参考本文时,那里只写login的情节即可)

4858美高梅 9

‘use strict’;

import { combineReducers } from ‘redux’;

import loginIn from ‘./loginReducer’; // 导入登录的redux处理进度

const rootReducer = combineReducers({ //
将全体的redux处理逻辑包装在一起

loginIn: loginIn,

});

export default rootReducer; // 导出,作为联合入口

7).创立项目中的store,用来治本全体的state

store文件夹内新建ConfigureStore.js文件

4858美高梅 10

‘use strict’;

import { createStore, applyMiddleware } from ‘redux’;

import thunkMiddleware from ‘redux-thunk’;

import rootReducer from ‘../reducers/index’;

const createStoreWithMiddleware =
applyMiddleware(thunkMiddleware)(createStore);

export default function configureStore(initialState) {

const store = createStoreWithMiddleware(rootReducer, initialState)

return store;

}

8).未来action,reducer,store都设有了,依据本身另一篇原理分析内的非视图部分已基本实现.

接下去大家在处理视图部分,即Provider.在那里自个儿个人习惯从外围往内写.先写Provider外壳,并将全部APP包裹在内;

src文件夹内,新建Root.js文件,该公文内完结Provider对视图部分的包装

4858美高梅 11

import React, { Component } from ‘react’;

import { Provider } from ‘react-redux’;

import configureStore from ‘./store/ConfigureStore’;

import App from ‘./container/App’;// app的入口

const store = configureStore();

export default class Root extends Component {  

    render() {    

        return (

            <Provider store={store}>

                <App />

           </Provider>

        ) 

    }

}

import App from ‘./container/App’;那里对应的是 app的入口
写到那里的时候,本文件还未曾实现

9).达成视图的片段代码

container文件夹内新建App.js文件,作为任何app的入口;

此地使用了react-navigation用来管理页面;

4858美高梅 12

import React, { Component } from ‘react’;

import {

View,

Text,

} from ‘react-native’;

import { StackNavigator } from ‘react-navigation’;

import LoginPage from ‘../pages/LoginPage’

import MainPage from ‘../pages/MainPage’

const App = StackNavigator({

Login: { screen: LoginPage },

Main: { screen: MainPage},

});

export default App

10.兑现页面(注意此处有很要紧的一步,要求在页面内实现组件和store的关系,之所以能够落到实处分裂的零部件关联差异的state也是在这一步举行的)

此地代码量较多,只粘贴关键代码

4858美高梅 13

红框部分:多reducer内选用差别的reducer

class LoginPage extends Component { 

 static navigationOptions = {    title: ‘LoginPage’,  };  

shouldComponentUpdate(nextProps, nextState) {    

// 登录成功,切成功登录   

 if (nextProps.status === ‘登陆成功’ && nextProps.isSuccess) {      

this.props.navigation.dispatch(resetAction)     

 return false;   

 }    

return true;  

 render() {    

const { login } = this.props;    

return(

/*…components*/

 }

}

export default connect(

(state) => ({

status: state.loginIn.status,

isSuccess: state.loginIn.isSuccess,

user: state.loginIn.user,

}),

(dispatch) => ({

login: () => dispatch(loginAction.login()),

})

)(LoginPage)

11).请我们自行完结加减法部分的逻辑并将其关系到相应的页面内.

1.设定时间的保有拍卖项目; type

2.轩然大波预处理进程; action

3.事件处理进程; reducer

4.透过reducer统一入口导出供外部使用;

5.达成视图pages并将其与逻辑部分绑定到一块儿;connect

可查阅demo代码

但愿本文对大家全体支持

有标题欢迎大家留言评论,会赶紧还原的

reducer
(reducer是三个函数),来展开操作,把意况改成了登录,怎么将情形来报告那些按钮呢?

4858美高梅 14

那就须求connect(接受行为)(模板)来进展收纳改变的消息。

接下去回去大家的App.js页面写我们的内容,大家在页面上定义多少个点击按钮,贰个增值,三个减值

4858美高梅 15

1 <div>计算器:{this.props.state.number}</div>
2 <button onClick={this.incCounter.bind(this)}>+</button>
3 <button onClick={this.decCounter.bind(this)}>-</button>

目录

接下去定义一下点击事件,并且把那几个点子传递给index.js页面包车型大巴法门

dispath()  发送行为如下

 1 constructor(){
 2      super()
 3      this.iAmount = 0
 4 }
 5 //将值传递给src/index.js里面的counter
 6 //增值
 7 incCounter(){
 8      this.props.dispatch({type:"INC",amount:++this.iAmount})
 9 }
10 //减值
11 decCounter(){
12     this.props.dispatch({type:"DEC",amount:--this.iAmount})
13 }

4858美高梅 16

 

action

明天这大家回到到index.js  写大家的格局

4858美高梅 17

 1 function counter(state={number:0},action) {
 2     switch (action.type) {
 3         case "INC":
 4             return{number: action.amount}
 5         case "DEC":
 6             return{number: action.amount}
 7         default:
 8             return state
 9     }
10 }

action的行为

以后大家的函数也定义完了,大家供给将它存放一下,大家在导入createStore和combineReducers

reducer主要片段   通过目录发现有五个文件,index.js,nav.js,login.js

1 import {createStore,combineReducers} from 'redux'

然后

4858美高梅 18

 1 let reducer=combineReducers(//合并多个函数
 2     {
 3         counter:counter,
 4     }
 5 )
 6 const store=createStore(reducer);
 7 class Index extends React.Component{
 8     render() {
 9        return (
10             <React.Fragment>
11                 <Provider store={store}>
12                     <App/>
13                 </Provider>
14             </React.Fragment>
15          );
16      }
17  }

index.js

好了当今我们着力大约就要实现了,就剩下最后的一点现行反革命我们回来到App.js导入二个connect以及变换一下导出组件的办法

4858美高梅 19

1 import { connect } from 'react-redux';
2 
3 export default connect((state)=>{
4     return {
5         state: state
6     }
7 })(App);

login.js

到近来为止,我们的这么些成效也马到功成了,

nav.js是路由的重定义的页面

愿意我们通过上述内容对redux有一个初叶的打听,以上内容有何样不足或许失实的地方,欢迎我们建议。

这么实在早已形成了贰个回路了:

login(dispatch链接) => action(dispatch链接) =>
 reducer函数(改变全局中的store内容) => store =>
 login(connect链接store)

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有