2017-11-25 151 views
2

我一直在努力围绕这个概念包扎我的头,但没有运气。 官方的React教程非常好,但对我来说它太复杂,只是有点太难。Redux如何更改React中的UI?

我想了解Redux和迄今为止我可以创建动作,reducer,我可以调度一个动作,然后看看它在调度它后如何更改存储状态。我也设法了解react-redux的connect,它工作的非常好,我可以在我的应用程序的任何地方触发分派。所以我想我几乎已经明白了。几乎,因为这里是房间里的大象 - 我发出行动,我看到了Redux状态的变化,但是我该如何更改UI?

比如我在初始状态text对象与价值Initial text而一旦按钮被点击我想文字更改为Clicked text,并在UI的地方显示的文字(让我们的按钮说)。

如何“访问”React中的Redux状态,以及如何动态改变它?

这似乎是非常简单的没有反应,例如::https://jsfiddle.net/loktar/v1kvcjbu/ - render函数处理一切,我明白这里发生的一切。

但是另一方面,官方React + Redux教程中的“todo”看起来像这样:https://redux.js.org/docs/basics/ExampleTodoList.html,它非常复杂,我不知道在哪里看。

Add Todo按钮提交表单发送dispatch(addTodo(input.value))动作。动作本身不做任何事情只是增加ID并将文本传递给商店,而reducer只是返回新的状态。那么如何在页面上呈现待办事项?哪里?我迷失在这一点上。也许有更简单的教程,我很想有一个单一的Redux教程它仍然可以复杂的多层组件:(

我怀疑在TodoList.js中发生的奇迹,因为他们映射的东西有,但我仍然不知道哪里来的待办事项从那里,它与终极版做什么(有没有简单的减速/动作/在该文件中派遣)。

感谢您的帮助!

+1

看看'mapStateToProps'函数,这是你失踪的最后一块。它会从redux状态更新组件的道具,从而在状态更改时触发重新渲染。 – xDreamCoding

回答

3

我觉得你的困惑是那部分reducer compositionselectors

让我们从相反的UI开始,以相反的顺序来看它。

在连接部件containers/VisibleTodoList.js它从“状态”(的redux全局存储对象)的内部mapStateToProps得到todos,而使其通过的getVisibleTodos方法。
可以称之为一个选择器,因为它选择并仅返回其接收到的数据的一部分:

import { connect } from 'react-redux' 
import { toggleTodo } from '../actions' 
import TodoList from '../components/TodoList' 

const getVisibleTodos = (todos, filter) => { 
    switch (filter) { 
    case 'SHOW_COMPLETED': 
     return todos.filter(t => t.completed) 
    case 'SHOW_ACTIVE': 
     return todos.filter(t => !t.completed) 
    case 'SHOW_ALL': 
    default: 
     return todos 
    } 
} 

const mapStateToProps = state => { 
    return { 
    todos: getVisibleTodos(state.todos, state.visibilityFilter) 
    } 
} 

const mapDispatchToProps = dispatch => { 
    return { 
    onTodoClick: id => { 
     dispatch(toggleTodo(id)) 
    } 
    } 
} 

const VisibleTodoList = connect(
    mapStateToProps, 
    mapDispatchToProps 
)(TodoList) 

export default VisibleTodoList 

state(Redux的商店)传递给mapStateToProps从根减速器reducers/index.js来到和实际上是一个单减速器(对象),其经由combineReducers效用的redux代表所有其他减速器的组合:

import { combineReducers } from 'redux' 
    import todos from './todos' 
    import visibilityFilter from './visibilityFilter' 

    const todoApp = combineReducers({ 
    todos, 
    visibilityFilter 
    }) 

    export default todoApp 

正如可以看到的,todos减速机在那里。所以这就是为什么在mapStateToProps里我们把它叫做这个state.todos

这里是reducers/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 

'ADD_TODO'类型的每个动作会返回一个新的状态,新的todo

case 'ADD_TODO': 
      return [ 
      ...state, 
      { 
       id: action.id, 
       text: action.text, 
       completed: false 
      } 
      ] 

它里面actions/index.js这个行动的创建者:

let nextTodoId = 0 
export const addTodo = text => { 
    return { 
    type: 'ADD_TODO', 
    id: nextTodoId++, 
    text 
    } 
} 

So h ere是redux的全部流程(我省略了调用动作的按钮,因为我认为这对你来说是显而易见的部分)。
好,几乎全流,没有这种可能发生而不Provider HOC封装了App并注入实体店就在index.js

import React from 'react' 
import { render } from 'react-dom' 
import { Provider } from 'react-redux' 
import { createStore } from 'redux' 
import todoApp from './reducers' 
import App from './components/App' 

let store = createStore(todoApp) 

render(
    <Provider store={store}> 
    <App /> 
    </Provider>, 
    document.getElementById('root') 
) 

现在,当reduxstate变化,mapStateToProps通话被调用,将返回新映射的propsconnect将通过这些新的props,这将触发一个新的render调用(实际上整个反应生命周期流)到连接的组件。
这种方式将使用来自商店的新数据重新呈现用户界面。

+1

以上是否有助于澄清混淆? –

1

连接时通常用于连接Reaction组件和Redux状态.connect是一个高阶组件,使用connect函数的组件封装在其中,方法签名为 connect([ma pStateToProps],[mapDispatchToProps],[mergeProps],[options]) mapStateToProps可以访问redux状态,并且mapDispathToProps可以访问store.dispatch。所有的道具都被合并并作为道具传递给底层组件。 Redux只有单一的真相状态。 store作为道具传递给Provider组件有一个名为store.getState()的方法。

因此,请记住一点,反应组件是数据驱动的。数据派生UI。只有当状态改变或道具已被修改时,React组件才会重新渲染。你可以在任何两个部分进行更改,组件会经历各种生命周期方法。

相关问题