redux应用程序



前言

原文链接:https://medium.com/@rajaraodv/step-by-step-guide-to-building-react-redux-apps-using-mocks-48ca0f47f9a

在React中,你可以创建不同的组件各自封装你需要的东西。之后你可以只渲染其中的一部分,这取决于应用的state。下面就来看看详细的介绍:

Redux正在成为构建React应用程序公认的方式。目前已经有大量的示例来说明展示其用法。但是React-Redux应用程序由好几个部分组成,如:ReducersActionsAction CreatorsStateMiddleware等,这些是难以理解的!

条件渲染

当我开始学习它的时候,我没有找到关于“React-Redux的哪个部分首先构建?”的文章或者“如何最佳的构建React-Redux应用程序”。所以我经历了几个例子和博客,并提出了如何处理大多数React
Redux应用程序的一般步骤。

可以根据state的值进行组件的条件渲染。例如:

为什么使用Redux?

React –
一个帮助我们把应用程序分解成多个组件的js库,但是react没有明确说明如何跟踪数据(state)以及如何正确的处理事件(action)

Redux –
一个免费的react库,其提供了一种轻松保存数据(state)和事件(action)的方法。

基本上Redux允许我们根据你的需要构建React应用程序,但将所有的state和action委托给Redux。

一个简单的todo应用程序有8个步骤,理论是,一些早期的框架在构建todo应用时非常简单,但是构建真实的应用程序很难,但是react
redux恰恰相反。

让我们开始:

function Greeting { const isLoggedIn = props.isLoggedIn; if  { return ; } return ;}ReactDOM.render( // Try changing to isLoggedIn={true}: , document.getElementById;

第一步:撰写一个详细的应用模拟

模拟需要包含所有的数据和视觉效果(如:列表项上面的删除线或者过滤里的“All”使用文字替代link)

图片 1

mock.png

你还可以用变量去存储组件,以便进行条件筛选,使得渲染函数的返回值更加清爽,例如:

第二步:将应用程序划分为组件

尝试根据每个组件的总体目的,将应用程序分为多个组件。

这里我们划分为3个组件:AddTodoTodoListFilter

图片 2

划分组件

class LoginControl extends React.Component { constructor; this.handleLoginClick = this.handleLoginClick.bind; this.handleLogoutClick = this.handleLogoutClick.bind; this.state = {isLoggedIn: false}; } handleLoginClick() { this.setState; } handleLogoutClick() { this.setState; } render() { const isLoggedIn = this.state.isLoggedIn; let button = null; if  { button = ; } else { button = ; } return (   {button}  ); }}ReactDOM.render( , document.getElementById;

Redux术语:ActionsState

每一个组件都包含两个事物:

  1. 根据一些数据渲染DOM,这些数据成为state
  2. 监听用户或其他事件并发送给js函数,这些被称作为action

还可以使用短操作符来实现条件筛选,可以用更短的代码写出渲染结果。例如&&来替代if,?:来替代if
else, 例如:

第三步:为每一个组件列出state和actions

请务必仔细查看第二步中的每一个组件,然后为它们列出state和actions列表。我们有3个组件AddTodoTodoListFilter,让我们来列出他们的action和state。

function Mailbox { const unreadMessages = props.unreadMessages; return (  Hello! {unreadMessages.length > 0 &&  You have {unreadMessages.length} unread messages.  }  );}const messages = ['React', 'Re: React', 'Re:Re: React']; ReactDOM.render( , document.getElementById;

render() { const isLoggedIn = this.state.isLoggedIn; return (  The user is {isLoggedIn ? 'currently' : 'not'} logged in.  );}

3.1 AddTodo组件:state和actions

在这个组件中,我们没有状态,因为组件外观和感觉根据任何数据都不会改变,但是需要让其他组件知道用户何时创建一个新的todo,我们称这个action为:ADD_TODO

图片 3

AddTodo

这种跟更大的表达式的写法也可以,但是不推荐,因为代码就不是很直观了。

3.2 TodoList 组件:state和actions

TodoList组件需要一个todo项的数组来渲染自己,所以它需要一个state:Todos(Array类型),除此之外,它还需要知道当前的Filter条件,来根据条件显示或隐藏todoitems,所以它还需要另外一个state,可以称为VisibilityFilter(boolen类型)。

再进一步,TodoList允许我们切换某个todoitem是否已经完成的状态而且还需要让其他组件知道这个切换,所以我们需要一个称为TOGGLE_TODO的action。

图片 4

todolist.png

render() { const isLoggedIn = this.state.isLoggedIn; return (  {isLoggedIn ? (  ) : (  )}  );}

3.3 Filter组件:state和actions

Filter组件根据条件是否激活来渲染成link或者一个简单的文字,这里需要一个state:CurrentFilter

当用户点击筛选条件时,Filter组件也需要告诉其它组件状态的切换,所以需要一个action:SET_VIBILITY_FILTER

图片 5

Filter.png

如果组件有时候需要渲染出来,而有时候不需要渲染出来,在不需要渲染的时候返回null即可。例如:

Redux术语:Action Creators

Action
Creators都是简单的函数,其主要职责是从DOM事件中接收数据,将其格式化为正式的Actionjson对象然后返回这个action对象。这有助于帮助我们规范化数据。

此外,它允许将来的任何其他组件也将这些动作发送给其他组件。

function WarningBanner { if  { return null; } return (  Warning!  );}class Page extends React.Component { constructor; this.state = {showWarning: true} this.handleToggleClick = this.handleToggleClick.bind; } handleToggleClick() { this.setState(prevState => ({ showWarning: !prevState.showWarning })); } render() { return (    {this.state.showWarning ? 'Hide' : 'Show'}   ); }}ReactDOM.render( , document.getElementById;

第四步:为每个action创建action creators

我们来为这三个(ADD_TODO,TOGGLE_TODO,SET_VISIBILITY_FILTER)action来创建action
creators。

// 1. 从AddTodo字段获取文本并返回适当的'Action'json对象,用以发送到其他组件
export const addTodo = (text) => {
    return {
        type: 'ADD_TODO',
        id: nextTodoId++,
        text, // ES6语法,相当于ES5中的text: text,
        completed: false // 默认未完成
    }
}

// 2. 获取过滤字符串并返回适当的'Action'json对象,用以发送到其他组件
export const setVisibilityFilter = (filter) => {
    return {
        type: 'SET_VISIBILITY_FILTER',
        filter
    }
}

// 3. 获取todo项的id并返回适当的'Action'json对象,用以发送到其他组件
export const toggleTodo = (id) => {
    return {
        type: 'TOGGLE_TODO',
        id
    }
}

总结

Redux术语:Reducers

Reducers是一个从Redux中接受state和”action”json对象的函数,其返回一个新的
state存储到Redux中。

  1. 当有用户操作时,Reducer函数将会被’Container’调用。
  2. 当reducer改变了state时,Redux会把新的state传递给每一个组件,react会重新渲染每一个组件。

举一个例子,下面的方法接受Redux的state(一个当前todos的数组),然后返回一个新的todos数组(new
state),当action的type为ADD_TODO时,一个新的todo将会被添加进去。

const todo = (state = [], action) => {
    switch (action.type) {
        case 'ADD_TODO':
            return [...state, {id: action.id, text: action.text, complete: false}];
    }
}

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

第五步:为每个action编写Reducers

注意:为了简洁,以下代码只是精简版,只是简单的展示了ADD_TODO,TOGGLE_TODO,SET_VISIBILITY_FILTER

const todo = (state, action) => {
    switch (action.type) {
        case 'ADD_TODO': 
            return [...state, {id: action.id, text: action.text, 
              completed:false}];
        case 'TOGGLE_TODO':
            return state.map(todo => {
                if (todo.id !== action.id) {
                    return todo
                }
                return Object.assign({}, todo, {completed: !todo.completed})
            });
        case 'SET_VISIBILITY_FILTER': {
            return action.filter;
        }

        default:
            return state;
    }
}

Redux术语:PresentationalContainer 组件

在每个组件中编写React和Redux的逻辑,可能会造成混乱,所以Redux推荐创建一个名为presentational的虚拟演示组件和一个名为Container的父包裹组件,用于处理Redux,dispatch
action等。

Container组件将数据传递给presentational组件,处理事件,代表presentational组件处理react。

图片 6

presentational

图例:黄色虚线为presentational组件,黑色虚线为Container组件

第六步:实现每个presentational组件

6.1 实现AddTodoForm presentational组件

图片 7

addtodoform.png

let AddTodoForm = ({onSubmit}) => {
    let input;
    return (
        <div>
            <form onSubmit={e => {onSubmit(input.value)}}>
                <input ref={node => {input = node}} />
                <button type="submit">Add todo</button>
            </form>
        </div>
    )
}

6.2 实现TodoList presentational 组件

图片 8

todoListpresentational.png

6.3 实现Link presentanional组件

图片 9

link.png

注意:在实际的代码中,Link
presentational组件被包装在FilterLink容器组件中。然后在Footer
presentational 组件中显示3个FilterLink组件。

第七步:为presentatinal组件创建Container组件

这是最后为每个组件连接Redux。

7.1 创建container component:AddTodo

图片 10

addtodocontainer.png

7.2 创建container component:TodoList Container

图片 11

todolistcontainer.png

7.3 创建container component:Filter Container

图片 12

filtercontainer.png

第八步:最终把他们结合到一起

import React from 'react' // ← Main React library
import { render } from 'react-dom' // ← Main react library
import { Provider } from 'react-redux' //← Bridge React and Redux
import { createStore } from 'redux' // ← Main Redux library
import todoApp from './reducers' // ← List of Reducers we created 
//Import all components we created earlier
import AddTodo from '../containers/AddTodo'
import VisibleTodoList from '../containers/VisibleTodoList'
import Footer from './Footer' // ← This is a presentational component that contains 3 FilterLink Container comp
//Create Redux Store by passing it the reducers we created earlier.
let store = createStore(reducers)
render(
    <Provider store={store}> ← The Provider component from react-redux injects the store to all the child components
        <div>
            <AddTodo />
            <VisibleTodoList />
            <Footer />
        </div>
    </Provider>,
 document.getElementById(‘root’) //<-- Render to a div w/ id "root"
)
标签:, , , , ,

相关文章

发表评论

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

网站地图xml地图