react-redux connect不会重新渲染组件,但是会更新道具

跟随

我有一个关于react-redux的问题,我正在玩一些小的测试代码,以了解其工作原理。

具有问题代码的Git存储库

一切看起来正确,动作生成器,reduce,dispatcher,mapStateToProps和connect函数。

我还将在这里粘贴代码:

没有状态突变。

但是,当子组件Todo(index.jsx)调用从主(有问题的组件)TodoBox(index.jsx)传递给它的函数(onClick事件)时,则1.调度器被触发2. reducer被触发并返回具有预期更新的新State 3 。mapStateToProps被触发并返回预期结果

但是TodoBox组件不会重新呈现从浏览器控制台中,我可以看到TodoBox的this.props具有更新的值。

我不明白发生了什么,检查了很多文章和示例,但没有找到匹配的结果。

谁可以发现问题,我需要帮助。

app.js(反应入口点)

import React from 'react';
import ReactDOM from 'react-dom';
import TodoBox from './views/index.jsx';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import * as actions from './redux_actions.js';

var data = JSON.parse(document.getElementById('initial-data').getAttribute('data-json'));

const todosReducer = function (state={todos: data}, action) {
  switch(action.type) {
    case actions.UPDATE_TODO:
        let newState = Object.assign({}, state)
        let upd1 = updateRow(newState.todos, 'titel', action.todoUpdate.id, 'checked', action.todoUpdate.checked)
        newState.todos = updateRow(upd1, 'titel', action.todoUpdate.id, 'detail', action.todoUpdate.checked ? 'Done' : 'Sorry not done')
        return newState
      break;
    default:
        return state;
  }
}

function updateRow(tab, where, val, updfield, val2) {
    tab.forEach( (row) => {
        row[where] === val ? row[updfield] = val2 : null
    })
    return tab
}

var Store = createStore(todosReducer)

ReactDOM.render(<Provider store={Store}><TodoBox /></Provider>, document.getElementById("app"));

index.jsx

import React from 'react';
import * as Redux from 'redux';
import { connect } from 'react-redux'
import * as actions from '../redux_actions.js'


class TodoBox extends React.Component {
        render() {
            return (
                <div className="todoBox">
                    <h1>Todos</h1>
                    <TodoList data={this.props.todos} func={this.props.handleChange}/>
                    <TodoForm />
                </div>
            );
        }
    }



class TodoList extends React.Component {
  render() {
     let todo = this.props.data.map( (todos) => { return <Todo titel={todos.titel} func={this.props.func} check={todos.checked} key={todos.titel}>{todos.detail}</Todo> } )
     return (
        <div className="todoList">
            <table style={{border: "2px solid black"}}>
              <tbody>
                 {todo}
              </tbody>
            </table>
        </div>
     );
  }
}


class Todo extends React.Component {
   render() {
    return (
      <tr>
        <td style={style.tableContent}>
           <input id={this.props.titel} type="checkbox" checked={this.props.checked} onChange={this.props.func}/>
        </td>
        <td style={style.tableContent}>{this.props.titel}</td>
        <td style={style.tableContent}>{this.props.children}</td>
      </tr>
    );
   }
}


Todo.propTypes = {
   titel: React.PropTypes.string.isRequired
}


class TodoForm extends React.Component {
  render() {
    return (
        <div className="todoForm">
        I am a TodoForm.
        </div>
     );
  }
}

let style = {
        tableContent: {
            border: "1px solid black"
        }
    };


const mapStateToProps = function (state) {
   return { todos: state.todos }
}

const mapDispatchToProps = function(dispatch) {
  return {
    handleChange: function(event) {
      dispatch(actions.actionUpdateTodo({id: event.target.id, checked: event.target.checked}));
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(TodoBox)

redux_actions.jsx

export const UPDATE_TODO = 'UPDATE_TODO'

export function actionUpdateTodo(todoUpdate) {
  return { type: UPDATE_TODO, todoUpdate: todoUpdate }
}

迪奥戈·斯格里洛(Diogo Sgrillo)

请检查http://redux.js.org/docs/Troubleshooting.html

看来您正在改变商店。问题出在您的减速器上。

我强烈建议您阅读纯函数

const todosReducer = function (state={todos: data}, action) {
  switch(action.type) {
    case actions.UPDATE_TODO:
        let newState = Object.assign({}, state)
        let upd1 = updateRow(newState.todos, 'titel', action.todoUpdate.id, 'checked', action.todoUpdate.checked)
        newState.todos = {...updateRow(upd1, 'titel', action.todoUpdate.id, 'detail', action.todoUpdate.checked ? 'Done' : 'Sorry not done')} //should do the trick. Although I would strongly suggest you to refactor the updateRow function.
        return newState //even so you are returning a newState, the reference value (todos) is not a new instance.
      break;
    default:
        return state;
  }
}

function updateRow(tab, where, val, updfield, val2) {
    tab.forEach( (row) => {
        row[where] === val ? row[updfield] = val2 : null
    })
    return tab
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

React + Redux:组件不更新

react / redux:立即通过调度更新道具后从状态获取最新的道具值

在react和redux-saga中从选择器更新道具后,如何使我的组件重新渲染?

React Redux容器组件

React Redux组件不更新

React / Redux存储更新,但组件未重新渲染

道具更改不会导致React重新渲染-Redux App

在Redux中更改状态后,React组件将不会重新渲染

React + Redux。Connect不会更新组件的状态

React组件不会使用Redux Pros重新渲染ChartJS图表

React-接收新道具时子组件不会更新

如何避免在React-Redux连接的组件中重新渲染?

使用Redux更改状态时,React组件不会重新渲染

Redux状态更改时,React不会重新渲染

派遣Redux Thunk重新渲染React组件

存储更改时,React Redux不会重新渲染

在redux状态的语言环境更新后重新渲染React组件

重新渲染React和Redux中的所有组件

React / Redux 组件重新渲染

React redux 不更新组件

React Redux 渲染连接组件

React-Redux:即使道具更改,组件也不会重新渲染

React/Redux 组件不会重新渲染

React Native - Redux ~ 没有被调用时更新道具

使用 Redux 和 React Hooks,Flatlist 不会重新渲染,也不会重新渲染其中的各个组件

React 组件道具不会使用 redux 商店更新

React Redux Connect 包装组件

从 redux 操作更改道具后,React 类组件不会重新渲染

ReduxToolkit useSelector Hook:通过 useDispatch 更新选定的 redux-state 后,React 功能组件不会重新渲染