Redux状态更改是什么

Redux状态更改是什么

在涉及”Redux状态更改”这个主题之前,我们应该先了解什么是Redux。

"A Predictable State Container for JS Apps"
JavaScript

换句话说,Redux是一种基于模式的库,用于管理和更新应用程序状态。为了管理和更新应用程序状态,Redux使用称为“action”的事件。

Redux具有一些特性,使其受欢迎,其中一些特性如下所述:

  • Redux具有可预测性属性,意味着它可以在不同的环境中运行,如客户端、服务器和本机。
  • Redux将应用程序状态集中到一个地方,您可以轻松执行撤消、重做、状态持久性等操作。
  • Redux还具有调试属性。换句话说,Redux具有称为Redux Devtools的工具,使应用程序易于调试,可以知道应用程序状态何时、在哪里、为什么以及如何发生变化。
  • 此外,Redux具有灵活性属性,可以适用于任何类型的UI层。

让我们举一个示例,以便更容易理解Redux。假设我们有一个食品应用程序,我们可以使用Redux存储库来管理食谱。为了管理应用程序中的食谱,我们有一些基本方法可以帮助我们做到这一点,例如:

我们只有一个 存储库 来管理整个应用程序的状态。同时, 操作方法 用于进行必要的更改。 Reducer 就像是安全保卫者,根据请求的操作方式知道如何改变状态。最后, 中间件 用于处理应用程序中执行的任务。

Redux状态更改是什么

随着时间的推移,应用程序的规模不断增长。此时,管理状态和调试状态对于应用程序来说是一个非常庞大的任务。管理状态并找到应用程序的状态何时何地发生变化也是一项挑战。有时候,当客户端调用某些API或对一些数据进行更改时,会在应用程序的状态上进行一些更新。因此,我们需要一个模型或管理系统来跟踪应用程序的状态。为此,使用了Redux,因为Redux是可预测的状态容器。为提供此服务,Redux使用了许多组件,如下所述:

  • 存储(Store)
  • Reducer
  • Action

1. Redux存储(Store): 在Redux中,Redux存储是Redux的主要组件(第一个基本原则)。因为所有的事物都通过Redux存储在应用程序中。Redux存储是一个单一存储,用于存储应用程序的所有状态和数据。Redux存储中发生的任何更改都会反映在整个应用程序中。因此,为了对状态进行必要的更改,我们执行以下步骤:

步骤1: 存储应用程序状态

存储的工作流程是:

  • 首先,Redux存储会获取应用程序状态的信息。
  • 然后,它会存储发生在状态上的更改。
  • 此后,存储会对应用程序的状态进行必要的更改。

Redux状态更改是什么

Redux状态中描述的帮助我们进行状态管理的函数如下所示:

  • getState()是用于获取有关应用程序当前状态的函数。
  • 更新状态时,Redux使用dispatch(action)。这是用于在应用程序中进行更新的一个函数。
  • 然后,存储库侦听状态中的更改。为此,Redux使用subscribe(listener)来查看更改并更新状态。

现在我们能够存储应用程序的当前状态。接下来,我们需要更新状态,以处理应用程序状态中的下一次更改。

步骤2: 更新应用程序的状态。为了进行必要的更改,或者可以说是为了进行应用程序状态的更新,我们使用操作。操作是Redux的主要组件,因为它具有一种特殊的属性,即类型属性,帮助Redux了解即将发生的状态更改。因此,我们可以说操作具有描述性质 类型 。

例如,我们要设计一个书店应用程序。然后用户想要向商店添加一本书。为此,我们使用操作函数来更改存储。操作调用类型属性如下所示:

{ type: "ADD_BOOK" }
JavaScript

为此,我们使用store.dispatch()函数。该函数被库用于接受在状态中执行的操作。这是Redux基础原理的第二条。

现在,通过所有这些,我们能够对应用程序的状态进行更新。现在我们使用这些操作来进行实际的更新。

步骤3: 通过reducers进行更改。为了在应用程序的状态中进行更改,我们使用纯函数。这些函数将当前状态作为参数并使用操作进行更改。然后返回更新后的应用程序状态。这些函数称为Reducers。这些函数在更改新的对象时不会操纵应用程序的状态,从而能够对应用程序状态进行管理或跟踪更改。Reducers的主要工作是收集一些值,将它们减少到更新后的状态,然后返回它。

因此,最终我们能够对应用程序进行更改。并且借助Store、Reducers和Actions跟踪每个状态。

让我们通过示例讨论Redux状态的变化:

示例: 在本节中,我们将讨论Redux状态变化的示例。以下是所需的步骤:在这里,我们将设计一个用于执行待办任务的react-redux应用程序。因此,我们需要执行以下步骤:

步骤1: 为了创建新的react应用程序,我们需要在终端中执行以下代码:

npx create-react-app todo
JavaScript

步骤2: 现在,在终端中创建并执行上述代码后,我们将得到一个名为 todo 的文件夹。 然后再次进入终端,键入:

cd todo
JavaScript

通过这个,我们可以说终端现在指向todo文件夹中的文件。

Redux状态更改是什么

步骤3: 这里我们将创建一个package.json文件,主要用于定义项目中要使用的依赖项。这就是我们创建这个文件的原因。

package.json:

{
    "name": "todos",
      "version": "0.0.1",
      "private": true,
      "devDependencies": {
        "react-scripts": "^4.0.3"
      },
      "dependencies": {
        "prop-types": "^15.7.2",
           "react": "^17.0.2",
        "react-dom": "^17.0.2",
        "react-redux": "^7.2.0",
        "redux": "^4.0.5"
      },
      "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "eject": "react-scripts eject",
        "test": "react-scripts test --env=node"
      },
      "browserslist": [
        ">0.2%",
        "not dead",
        "not ie <= 11",
        "not op_mini all"
      ]
}
JavaScript

在定义依赖关系之后,我们必须通过在终端中键入以下代码来安装它们:

注意: 建议在项目中使用终端,用于启动服务器或安装所需的依赖项。

npm install
JavaScript

步骤4: 创建必要的文件。在上述步骤完成之后,我们的todo文件夹中有以下文件:

  • node_modules
  • public
  • src
  • package-lock.json
  • package.json

现在,删除public和src文件中的所有文件。所以,在执行这些操作之后,我们将创建以下文件:

在public文件夹中创建文件 index.html. index.html文件基本上用于获取应用程序所需的所有数据。它是应用程序的主页。

index.html

<!doctype html> 
<html lang="en"> 
  
<head> 
    <meta charset="utf-8"> 
    <meta name="viewport" content= 
          "width=device-width, initial-scale=1"> 
    <title>Redux Todo List</title> 
</head> 
  
<body> 
    <div id="root"></div> 
</body> 
  
</html>
JavaScript

现在,我们要创建以下文件夹和文件:

  • actions
  • components
  • containers
  • reducers
  • index.js

index.js文件: 它是用来提取所有文件的数据的文件,比如存储、减速器、行动等。或者我们可以说它是react-redux应用程序的存储。所有容器都需要访问它以获取进一步处理的数据,如更新、更改等等。

import React from 'react'
import { render } from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import App from './components/App'
import rootReducer from './reducers'
  
const store = createStore(rootReducer) 
  
render( 
    <Provider store={store}> 
        <App /> 
      </Provider>, 
      document.getElementById('root') 
)
JavaScript

actions 文件夹中,我们使用称为“ type ”的属性,用于通知发送到存储的数据。我们将创建以下文件:

  • index.js
  • index.spec.js

index.js文件: 在这个文件中,创建了一个要创建的操作,它还提供了它的id(唯一的数字或标识符)。同时也定义了当前操作的可见性过滤器active。

let nextTodoId = 0 
export const addTodo = text => ({ 
    type: 'ADD_TODO', 
    id: nextTodoId++, 
    text 
}) 
  
export const setVisibilityFilter = filter => ({ 
    type: 'SET_VISIBILITY_FILTER', 
    filter 
}) 
  
export const toggleTodo = id => ({ 
    type: 'TOGGLE_TODO', 
    id 
}) 
  
export const VisibilityFilters = { 
    SHOW_ALL: 'SHOW_ALL', 
    SHOW_COMPLETED: 'SHOW_COMPLETED', 
    SHOW_ACTIVE: 'SHOW_ACTIVE'
}
JavaScript

index.spec.js:

import * as actions from './index'
  
describe('todo actions', () => { 
    it('addTodo should create ADD_TODO action', () => { 
        expect(actions.addTodo('Use Redux')).toEqual({ 
            type: 'ADD_TODO', 
            id: 0, 
            text: 'Use Redux'
        }) 
    }) 
  
    it('setVisibilityFilter should create  
        SET_VISIBILITY_FILTER action', () => { 
        expect(actions.setVisibilityFilter('active')).toEqual({ 
            type: 'SET_VISIBILITY_FILTER', 
            filter: 'active'
        }) 
    }) 
  
    it('toggleTodo should create TOGGLE_TODO action', () => { 
        expect(actions.toggleTodo(1)).toEqual({ 
            type: 'TOGGLE_TODO', 
            id: 1 
        }) 
    }) 
})
JavaScript

步骤5: 在此之后,我们将在 components 文件夹中创建以下文件:

  • App.js
  • Footer.js
  • Link.js
  • Todo.js
  • TodoList.js

组件文件夹是React-Redux应用程序的展示部分,意味着我们在该文件夹中定义与应用程序的外观相关的文件,如样式、布局等等。它仅用于接收数据并通过props渲染数据。

App.js文件: 它是主要的或者可以说是根组件,需要在应用程序的用户界面上渲染。

import React from 'react'
import Footer from './Footer'
import AddTodo from '../containers/AddTodo'
import VisibleTodoList from '../containers/VisibleTodoList'
  
const App = () => ( 
    <div> 
        <AddTodo /> 
        <VisibleTodoList /> 
        <Footer /> 
    </div> 
) 
  
export default App
JavaScript

Footer.js 文件: 在这个文件(或者说是在用户创建的应用程序中)决定哪些更改应该在哪里可见。

import React from 'react'
import FilterLink from '../containers/FilterLink'
import { VisibilityFilters } from '../actions'
  
const Footer = () => ( 
    <div> 
        <span>Show: </span> 
        <FilterLink filter={VisibilityFilters.SHOW_ALL}> 
            All 
        </FilterLink> 
        <FilterLink filter={VisibilityFilters.SHOW_ACTIVE}> 
            Active 
        </FilterLink> 
        <FilterLink filter={VisibilityFilters.SHOW_COMPLETED}> 
            Completed 
        </FilterLink> 
    </div> 
) 
  
export default Footer
JavaScript

Link.js文件: 用于使用决定当前状态的回调函数,例如active,completed等的动作。

import React from 'react'
import PropTypes from 'prop-types'
  
const Link = ({ active, children, onClick }) => ( 
    <button 
        onClick={onClick} 
        disabled={active} 
        style={{ 
            marginLeft: '4px', 
        }} 
    > 
        {children} 
    </button> 
) 
  
Link.propTypes = { 
    active: PropTypes.bool.isRequired, 
    children: PropTypes.node.isRequired, 
    onClick: PropTypes.func.isRequired 
} 
  
export default Link
JavaScript

Todo.js 文件: 用于表示单个 todo 项目。

import React from 'react'
import PropTypes from 'prop-types'
  
const Todo = ({ onClick, completed, text }) => ( 
    <li 
        onClick={onClick} 
        style={{ 
            textDecoration: completed ? 'line-through' : 'none'
        }} 
    > 
        {text} 
    </li> 
) 
  
Todo.propTypes = { 
    onClick: PropTypes.func.isRequired, 
    completed: PropTypes.bool.isRequired, 
    text: PropTypes.string.isRequired 
} 
  
export default Todo
JavaScript

TodoList.js文件:

用于显示当前状态下可用的待办事项,格式为{id,text,completed}

import React from 'react'
import PropTypes from 'prop-types'
import Todo from './Todo'
  
const TodoList = ({ todos, toggleTodo }) => ( 
    <ul> 
        {todos.map(todo => 
            <Todo 
                key={todo.id} 
                {...todo} 
                onClick={() => toggleTodo(todo.id)} 
            /> 
        )} 
    </ul> 
) 
  
TodoList.propTypes = { 
    todos: PropTypes.arrayOf(PropTypes.shape({ 
        id: PropTypes.number.isRequired, 
        completed: PropTypes.bool.isRequired, 
        text: PropTypes.string.isRequired 
    }).isRequired).isRequired, 
    toggleTodo: PropTypes.func.isRequired 
} 
  
export default TodoList
JavaScript

现在,我们将在 containers 文件夹中创建以下文件:

  • AddTodo.js
  • FilterLink.js
  • VisibleTodoList.js

在容器组件中,正如我们之前学到的,它始终关注于工作的事物,即数据如何被获取到其他文件中或者更新如何发生。它为组件提供数据,或者可以说为在UI中呈现的组件提供布局数据。它还使用redux状态功能来读取和分发redux操作,以更新当前UI组件中的数据。

AddTodo.js文件: 它包含用户希望通过“添加”(提交)按钮添加到待办事项列表中的待办事项文本。

import React from 'react'
import { connect } from 'react-redux'
import { addTodo } from '../actions'
  
const AddTodo = ({ dispatch }) => { 
    let input 
  
    return ( 
        <div> 
            <form onSubmit={e => { 
                e.preventDefault() 
                if (!input.value.trim()) { 
                    return
                } 
                dispatch(addTodo(input.value)) 
                input.value = ''
            }}> 
                <input ref={node => input = node} /> 
                <button type="submit"> 
                    Add Todo 
                </button> 
            </form> 
        </div> 
    ) 
} 
  
export default connect()(AddTodo)
JavaScript

FilerLink.js 文件: 用于设置需要设置在待办事项当前状态上的可见性过滤器。

import { connect } from 'react-redux'
import { setVisibilityFilter } from '../actions'
import Link from '../components/Link'
  
const mapStateToProps = (state, ownProps) => ({ 
    active: ownProps.filter === state.visibilityFilter 
}) 
  
const mapDispatchToProps = (dispatch, ownProps) => ({ 
    onClick: () => dispatch(setVisibilityFilter(ownProps.filter)) 
}) 
  
export default connect( 
    mapStateToProps, 
    mapDispatchToProps 
)(Link) 
JavaScript

VisibleTodoList.js文件: 它过滤并在应用程序页面上呈现项目。

import { connect } from 'react-redux'
import { toggleTodo } from '../actions'
import TodoList from '../components/TodoList'
import { VisibilityFilters } from '../actions'
  
const getVisibleTodos = (todos, filter) => { 
    switch (filter) { 
        case VisibilityFilters.SHOW_ALL: 
            return todos 
        case VisibilityFilters.SHOW_COMPLETED: 
            return todos.filter(t => t.completed) 
        case VisibilityFilters.SHOW_ACTIVE: 
            return todos.filter(t => !t.completed) 
        default: 
            throw new Error('Unknown filter: ' + filter) 
    } 
} 
  
const mapStateToProps = state => ({ 
    todos: getVisibleTodos(state.todos, state.visibilityFilter) 
}) 
  
const mapDispatchToProps = dispatch => ({ 
    toggleTodo: id => dispatch(toggleTodo(id)) 
}) 
  
export default connect( 
    mapStateToProps, 
    mapDispatchToProps 
)(TodoList) 
JavaScript

步骤6: 现在,我们将在 reducers 文件夹中创建以下文件:

  • index.js
  • todos.js
  • todos.spec.js
  • visibilityFilter.js

正如我们之前学到的,动作仅用于对应用程序进行更改,而reducer用于在应用程序中呈现这些更改。因此,reducer是一个接受两个参数“Action”和“State”的函数。它读取动作发送的数据,并通过redux功能在“store”中更新它。

index.js文件:

import { combineReducers } from 'redux'
import todos from './todos'
import visibilityFilter from './visibilityFilter'
  
export default combineReducers({ 
    todos, 
      visibilityFilter 
})
JavaScript

todos.js文件:

const todos = (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 => 
                (todo.id === action.id) 
                    ? { ...todo, completed: !todo.completed } 
                    : todo 
            ) 
        default: 
            return state 
    } 
} 
  
export default todos
JavaScript

todos.spec.js文件:

import todos from './todos'
  
describe('todos reducer', () => { 
    it('should handle initial state', () => { 
        expect( 
            todos(undefined, {}) 
        ).toEqual([]) 
    }) 
  
    it('should handle ADD_TODO', () => { 
        expect( 
            todos([], { 
                type: 'ADD_TODO', 
                text: 'Run the tests', 
                id: 0 
            }) 
        ).toEqual([ 
            { 
                text: 'Run the tests', 
                completed: false, 
                id: 0 
            } 
        ]) 
  
        expect( 
            todos([ 
                { 
                    text: 'Run the tests', 
                    completed: false, 
                    id: 0 
                } 
            ], { 
                type: 'ADD_TODO', 
                text: 'Use Redux', 
                id: 1 
            }) 
        ).toEqual([ 
            { 
                text: 'Run the tests', 
                completed: false, 
                id: 0 
            }, { 
                text: 'Use Redux', 
                completed: false, 
                id: 1 
            } 
        ]) 
  
        expect( 
            todos([ 
                { 
                    text: 'Run the tests', 
                    completed: false, 
                    id: 0 
                }, { 
                    text: 'Use Redux', 
                    completed: false, 
                    id: 1 
                } 
            ], { 
                type: 'ADD_TODO', 
                text: 'Fix the tests', 
                id: 2 
            }) 
        ).toEqual([ 
            { 
                text: 'Run the tests', 
                completed: false, 
                id: 0 
            }, { 
                text: 'Use Redux', 
                completed: false, 
                id: 1 
            }, { 
                text: 'Fix the tests', 
                completed: false, 
                id: 2 
            } 
        ]) 
    }) 
  
    it('should handle TOGGLE_TODO', () => { 
        expect( 
            todos([ 
                { 
                    text: 'Run the tests', 
                    completed: false, 
                    id: 1 
                }, { 
                    text: 'Use Redux', 
                    completed: false, 
                    id: 0 
                } 
            ], { 
                type: 'TOGGLE_TODO', 
                id: 1 
            }) 
        ).toEqual([ 
            { 
                text: 'Run the tests', 
                completed: true, 
                id: 1 
            }, { 
                text: 'Use Redux', 
                completed: false, 
                id: 0 
            } 
        ]) 
    }) 
})
JavaScript

visibilityFilter.js 文件:

import { VisibilityFilters } from '../actions'
  
const visibilityFilter = (state = VisibilityFilters.SHOW_ALL, action) => { 
    switch (action.type) { 
        case 'SET_VISIBILITY_FILTER': 
            return action.filter 
        default: 
            return state 
    } 
} 
  
export default visibilityFilter
JavaScript

运行应用程序的步骤: 在执行上述步骤后,我们完成了我们的Redux管理应用程序。要启动该应用程序,我们应该在终端中输入。

npm start
JavaScript

输出:

Redux状态更改是什么

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册