如何在Redux中更改商店时重新渲染组件?

问题描述:

我试图让我的终极版第一个应用程序,我已经做了一个版本的这一点没有终极版,我知道终极版不一定需要这一点,但我想学习终极版。如何在Redux中更改商店时重新渲染组件?

我有有待办事项的阵列商店,我的行动成功调度,并更新商店。

我的任务组件列表连接到存储和数组作为它自己的组件中呈现的每个项目。

初始加载,我的待办事项清单显示,从商店的初始状态的待办事项,但一旦我更新从状态的新项目没有得到呈现。相反,返回组件数组的map方法表示它'不能读取未定义的属性'map'。

如何解决这个问题?

干杯。

import React from 'react'; 
 
import ReactDOM from 'react-dom'; 
 
import { createStore } from 'redux'; 
 
import { Provider } from 'react-redux'; 
 
import Container from './components/Container.js' 
 
import TaskReducer from './reducers/Task.js' 
 

 
require("./index.css"); 
 

 
const defaultState = { 
 
    items: [ 
 
    "task 1", 
 
    "task 2" 
 
    ] 
 
}; 
 

 
const store = createStore(TaskReducer, defaultState); 
 

 
// Allows access to store in console log 
 
window.store = store; 
 

 
ReactDOM.render((
 
    <Provider store={store}> 
 
    <Container /> 
 
    </Provider> 
 
), 
 
    document.getElementById('wrapper') 
 
);

import React from 'react'; 
 
import ReactDOM from 'react-dom'; 
 
import TaskList from './TaskList.js'; 
 
import { createStore, bindActionCreators } from 'redux'; 
 
import * as ActionCreators from '../actions/Task.js'; 
 
import Redux from 'redux'; 
 
import {connect} from 'react-redux' 
 

 
class Container extends React.Component { 
 
    constructor() { 
 
    super(); 
 
    } 
 

 
    render() { 
 
    // What does this do??? 
 
    const {dispatch} = this.props; 
 
    const deleteItem = bindActionCreators(ActionCreators.deleteTodoItem, dispatch); 
 
    const addItem = bindActionCreators(ActionCreators.addTodoItem, dispatch); 
 

 
    function _onSubmit(e) { 
 
     e.preventDefault(); 
 
     addItem(e.target.elements.task.value); 
 
     // Resets the form 
 
     e.target.reset(); 
 
    } 
 

 
    return (
 
     <div className=""> 
 
     <header className="header"> 
 
      <h1>To Do:</h1> 
 
     </header> 
 
      <form autoComplete="off" onSubmit={_onSubmit}> 
 
      <input name="task" placeholder="Task" autoComplete="off"></input> 
 
      </form> 
 
      <TaskList /> 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
const mapStateToProps = state => (
 
\t { 
 
\t \t items: state.items 
 
\t } 
 
); 
 

 
export default connect(mapStateToProps)(Container);

import React from 'react'; 
 
import Task from './Task'; 
 
import { connect } from 'react-redux'; 
 

 
let TaskList = (props) => { 
 
    console.log('items', props.items); 
 
    var tasks = (props.items).map((item, key) => { return <Task data={item} key={key} listItemKey={key} /> }) 
 

 
    return(
 
    <ul className="task-list"> 
 
     {tasks} 
 
    </ul> 
 
); 
 
} 
 

 
const mapStateToProps = state => (
 
\t { 
 
\t \t items: state.items 
 
\t } 
 
); 
 

 
export default connect(mapStateToProps)(TaskList);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

import * as action from '../actions/Task.js' 
 

 
export default function toDoItems(state = [], action) { 
 
    switch(action.type) { 
 
    case 'DELETE_ITEM': 
 
     return [ 
 
     ...state, 
 
     ]; 
 

 
    case 'ADD_ITEM': 
 
     console.log('ADD ITEM'); 
 
     console.log('Submitted value = ', action.submittedValue) 
 
     return [ 
 
     ...state, 
 
     // Reducer gets action object item and appends to array 
 
     action.submittedValue 
 
     ] 
 

 
    default: 
 
     return state; 
 
    } 
 
}

---减速---

import * as action from '../actions/Task.js' 
 

 
export default function toDoItems(state = [], action) { 
 
    switch(action.type) { 
 
    case 'DELETE_ITEM': 
 
     return [ 
 
     ...state, 
 
     ]; 
 

 
    case 'ADD_ITEM': 
 
     console.log('ADD ITEM'); 
 
     console.log('Submitted value = ', action.submittedValue); 
 
     console.log('the state', state); 
 
     return [ 
 
     ...state, 
 
     // Reducer gets action object item and appends to array 
 
     action.submittedValue 
 
     ] 
 

 
    default: 
 
     return state; 
 
    } 
 
}

--- ---行动

export function addTodoItem(submittedValue) { 
 
    return { 
 
     type: 'ADD_ITEM', 
 
     // The action object returned has the submittedValue 
 
     submittedValue 
 
    } 
 
} 
 

 
export function deleteTodoItem() { 
 
    return { 
 
     type: 'DELETE_ITEM', 
 
    } 
 
}

我已经编辑任务列表的组成部分。你没有使用地图功能正常

import React from 'react'; 
 
import Task from './Task'; 
 
import { connect } from 'react-redux'; 
 

 
let TaskList = (props) => { 
 
console.log('items', props.items); 
 
var tasks = undefined; 
 
if(props.items && props.items.length > 0){ 
 
    tasks = props.items.map((item, key) => { return <Task data={item} 
 
    key={key} listItemKey={key} /> }) 
 
} //edited code 
 

 
    return(
 
    <ul className="task-list"> 
 
     {tasks} 
 
    </ul> 
 
); 
 
} 
 

 
const mapStateToProps = state => (
 
\t { 
 
\t \t items: state.items 
 
\t } 
 
); 
 

 
export default connect(mapStateToProps)(TaskList);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

至于商店使用以下方法来配置存储在您的主文件。 ...

import TaskReducer from './reducers/Task.js'; 
import * as redux from 'redux'; 
function configure(initialState = {}){ 
    const reducers = redux.combineReducers({ 
     tasks : TaskReducer 
    }); 

    let store = redux.createStore(reducers, initialState); 

    return store; 
}; 

const store = configure(); 
// Allows access to store in console log 
window.store = store; 

ReactDOM.render((
    <Provider store={store}> 
    <Container /> 
    </Provider> 
), 
    document.getElementById('wrapper') 
); 
+0

这可以防止错误和我的状态更新,但它仍然不会呈现页面上的任何内容。我开始认为我错过了对Redux非常重要的事情。看来,只要我更新状态,而状态正确更新,组件的道具变得不确定。 – tomhughes

+0

在渲染方法中,如果您执行“console.log(道具)”,会得到什么? –

+0

Props使用items数组和派发方法返回一个对象。我怀疑这个问题可能与我的reducer有关,我现在将添加源代码。 – tomhughes