Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React Redux无法使减速器拾取动作_Javascript_Reactjs_Redux_React Redux - Fatal编程技术网

Javascript React Redux无法使减速器拾取动作

Javascript React Redux无法使减速器拾取动作,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,我一直在学习redux&react,并且正在建立一个待办事项列表。我一直在阅读和阅读不同的文章,但无法找出我在设置中遗漏了什么 目前,您可以通过输入添加todo。按enter键时,它会发送带有todo文本的addTodo操作 我希望reducer能够看到动作类型并更新状态,但它从来没有这样做过。我错过了什么 index.jsx import React from 'react'; import ReactDOM from 'react-dom'; import { createStore } f

我一直在学习redux&react,并且正在建立一个待办事项列表。我一直在阅读和阅读不同的文章,但无法找出我在设置中遗漏了什么

目前,您可以通过输入添加todo。按enter键时,它会发送带有todo文本的
addTodo
操作

我希望reducer能够看到动作类型并更新状态,但它从来没有这样做过。我错过了什么

index.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import reducer from './reducer.js';
import TodoList from './containers/container.js';

const store = createStore(reducer);

ReactDOM.render(
  <Provider store={store}>
    <TodoList />
  </Provider>,
document.getElementById('app'));
import React from 'react';
import TodoComponent from './TodoComponent.jsx';
import { addTodo } from '../actions/actions.js'

export default class TodoList extends React.Component {

  render () {
    const { todos } = this.props;

    return (
      <div>
        <input type='text' placeholder='Add todo' onKeyDown={this.onSubmit} />
        <ul>
          {todos.map(c => (
            <li key={t.id}>
              <TodoComponent todo={t} styleName='large' />
            </li>
          ))}
        </ul>
      </div>
    )
  }

  onSubmit(e) {
    const input = e.target;
    const text = input.value;
    const isEnterKey = (e.which === 13);

    if (isEnterKey) {
      input.value = '';
      addTodo(text);
    }
  }

}
import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './style.css';

export default class TodoComponent extends React.Component {

  render () {
    const { todo } = this.props;

    return (
      <div styleName='large'>{todo.text}</div>
    )
  }
}

export default CSSModules(TodoComponent, styles);
TodoListComponent.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import reducer from './reducer.js';
import TodoList from './containers/container.js';

const store = createStore(reducer);

ReactDOM.render(
  <Provider store={store}>
    <TodoList />
  </Provider>,
document.getElementById('app'));
import React from 'react';
import TodoComponent from './TodoComponent.jsx';
import { addTodo } from '../actions/actions.js'

export default class TodoList extends React.Component {

  render () {
    const { todos } = this.props;

    return (
      <div>
        <input type='text' placeholder='Add todo' onKeyDown={this.onSubmit} />
        <ul>
          {todos.map(c => (
            <li key={t.id}>
              <TodoComponent todo={t} styleName='large' />
            </li>
          ))}
        </ul>
      </div>
    )
  }

  onSubmit(e) {
    const input = e.target;
    const text = input.value;
    const isEnterKey = (e.which === 13);

    if (isEnterKey) {
      input.value = '';
      addTodo(text);
    }
  }

}
import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './style.css';

export default class TodoComponent extends React.Component {

  render () {
    const { todo } = this.props;

    return (
      <div styleName='large'>{todo.text}</div>
    )
  }
}

export default CSSModules(TodoComponent, styles);
reducer.js

var uuid = require('node-uuid');

export function addTodo(text) {
  console.log('action addTodo', text);
  return {
    type: 'ADD_TODO',
    payload: {
      id: uuid.v4(),
      text: text
    }
  };
}
import { connect } from 'react-redux';
import TodoList from '../components/TodoListComponent.jsx';
import { addTodo } from '../actions/actions.js';

const mapStateToProps = (state) => {
   return {
      todos: state
   }
};

const mapDispatchToProps = (dispatch) => {
   return {
      addTodo: text => dispatch(addTodo(text))
   }
};

export default connect(mapStateToProps, mapDispatchToProps)(TodoList);
import { List, Map } from 'immutable';

const init = List([]);

export default function(todos = init, action) {

  console.log('reducer action type', action.type);

  switch(action.type) {
    case 'ADD_TODO':
      console.log('ADD_TODO');
      return todos.push(Map(action.payload));
    default:
      return todos;
  }
}

TodoListComponent
中,您直接从操作文件导入操作,但实际上您希望使用映射到容器中的dispatch和pass属性的操作。这就解释了为什么您会看到来自操作的日志,而不是来自reducer的日志,因为操作从未被分派到存储区

因此,您的
ToDoList组件应该是:

import React from 'react';
import TodoComponent from './TodoComponent.jsx';

export default class TodoList extends React.Component {

  render () {
    const { todos } = this.props;

    return (
      <div>
        <input type='text' placeholder='Add todo' onKeyDown={this.onSubmit} />
        <ul>
          {todos.map(c => (
            <li key={t.id}>
              <TodoComponent todo={t} styleName='large' />
            </li>
          ))}
        </ul>
      </div>
    )
  }

  onSubmit(e) {
    const input = e.target;
    const text = input.value;
    const isEnterKey = (e.which === 13);

    if (isEnterKey) {
      input.value = '';
      this.props.addTodo(text);
    }
  }

}
从“React”导入React;
从“/TodoComponent.jsx”导入TodoComponent;
导出默认类TodoList扩展React.Component{
渲染(){
const{todos}=this.props;
返回(
    {todos.map(c=>(
  • ))}
) } 提交(e){ 常量输入=e.目标; 常量文本=input.value; 常数IsInterkey=(e.which==13); 如果(ISINTERKEY){ input.value=''; this.props.addTodo(text); } } }
在您的
TodoListComponent
中,您直接从操作文件导入操作,但实际上您希望使用映射到容器中的dispatch and pass as属性的操作。这就解释了为什么您会看到来自操作的日志,而不是来自reducer的日志,因为操作从未被分派到存储区

因此,您的
ToDoList组件应该是:

import React from 'react';
import TodoComponent from './TodoComponent.jsx';

export default class TodoList extends React.Component {

  render () {
    const { todos } = this.props;

    return (
      <div>
        <input type='text' placeholder='Add todo' onKeyDown={this.onSubmit} />
        <ul>
          {todos.map(c => (
            <li key={t.id}>
              <TodoComponent todo={t} styleName='large' />
            </li>
          ))}
        </ul>
      </div>
    )
  }

  onSubmit(e) {
    const input = e.target;
    const text = input.value;
    const isEnterKey = (e.which === 13);

    if (isEnterKey) {
      input.value = '';
      this.props.addTodo(text);
    }
  }

}
从“React”导入React;
从“/TodoComponent.jsx”导入TodoComponent;
导出默认类TodoList扩展React.Component{
渲染(){
const{todos}=this.props;
返回(
    {todos.map(c=>(
  • ))}
) } 提交(e){ 常量输入=e.目标; 常量文本=input.value; 常数IsInterkey=(e.which==13); 如果(ISINTERKEY){ input.value=''; this.props.addTodo(text); } } }
从“React”导入React;
从“/TodoComponent.jsx”导入TodoComponent;
导出默认类TodoList扩展React.Component{
渲染(){
const{todos}=this.props;
返回(
    {todos.map(c=>(
  • ))}
) } 提交(e){ //使用通过connect传递的addTodo const{addTodo}=this.props; 常量输入=e.目标; 常量文本=input.value; 常数IsInterkey=(e.which==13); 如果(ISINTERKEY){ input.value=''; addTodo(文本); } } }
从“React”导入React;
从“/TodoComponent.jsx”导入TodoComponent;
导出默认类TodoList扩展React.Component{
渲染(){
const{todos}=this.props;
返回(
    {todos.map(c=>(
  • ))}
) } 提交(e){ //使用通过connect传递的addTodo const{addTodo}=this.props; 常量输入=e.目标; 常量文本=input.value; 常数IsInterkey=(e.which==13); 如果(ISINTERKEY){ input.value=''; addTodo(文本); } } }
TodoListComponent.jsx
中,您应该使用
addTodo
通过
connect
传入的
props
作为下面答案的旁注,在Redux中工作时,您的还原程序应该始终返回一个新的状态实例,而不是操纵当前状态,而不是
返回todos.push(Map(action.payload));
这会改变您应该使用的当前数组
返回todos.concat(Map(action.payload))
它将从您当前的状态和操作负载返回一个新数组。在
TodoListComponent.jsx
中,您应该使用
addTodo
通过
connect
传递给
addTodo
作为下面答案的旁注,在Redux中工作时,您的还原程序应该始终返回一个新的状态实例,而不是mani填充当前状态,而不是
返回todos.push(Map(action.payload));
这会改变当前数组,您应该使用
返回todos.concat(Map(action.payload));
它将从您当前的状态返回一个新数组&操作负载。感谢您的解释,这是有意义的。这样做,您的答案缺少了@opheman answer中建议的“onKeyDown={this.onSubmit.bind(this)}”。感谢您的解释,这是有意义的。这样做,您的答案缺少了“onKeyDown”={this.onSubmit.bind(this)}`这是@opheman答案中建议的。