`App` 中未指定所需道具 `visibleTodos[0].text`

Required prop `visibleTodos[0].text` was not specified in `App`

拜托,我正在尝试将示例 Here 作为 react-react 教程。但是,当 onTodoClick 失败并出现以下错误

时,该代码有效

Warning: Failed propType: Required propvisibleTodos[0].textwas not specified inA​​pp. Check the render method ofConnect(App).

Warning: Failed propType: Required proptodos[0].textwas not specified inTodoList. Check the render method ofApp.

下面是我的App.js

class App extends Component {
    render(){
        // Injected by connect() call:
    const { dispatch, visibleTodos, visibilityFilter } = this.props
        return (
          <div>
                <AddTodo
                    onAddClick={text =>
                    dispatch(addTodo(text))
              } />
                <TodoList
                    todos={visibleTodos}
                    onTodoClick={id =>
                    dispatch(completeTodo(id))
              } />
                <Footer
                    filter={visibilityFilter}
                    onFilterChange={nextFilter =>
                    dispatch(setVisibilityFilter(nextFilter))
              } />
          </div>
        )
    }
}
App.propTypes = {
  visibleTodos: PropTypes.arrayOf(PropTypes.shape({
    text: PropTypes.string.isRequired,
    completed: PropTypes.bool.isRequired
  }).isRequired).isRequired,
  visibilityFilter: PropTypes.oneOf([
    'SHOW_ALL',
    'SHOW_COMPLETED',
    'SHOW_ACTIVE'
  ]).isRequired
}

function selectTodos(todos, filter) {
  switch (filter) {
    case VisibilityFilters.SHOW_ALL:
      return todos
    case VisibilityFilters.SHOW_COMPLETED:
      return todos.filter(todo => todo.completed)
    case VisibilityFilters.SHOW_ACTIVE:
      return todos.filter(todo => !todo.completed)
  }
}

function select(state) {
  return {
    visibleTodos: selectTodos(state.todos, state.visibilityFilter),
    visibilityFilter: state.visibilityFilter
  }
}

export default connect(select)(App)

和我的 TodoList

import React, { Component, PropTypes } from 'react'
import Todo from './Todo'

export default class TodoList extends Component{
    render(){
        return(
            <ul>
                {this.props.todos.map((todo, index) =>
                    <Todo {...todo}
                        key={index}
                        onClick={() => this.props.onTodoClick(index)} />
                )}

            </ul>
        )
    }
}

TodoList.propTypes = {
  onTodoClick: PropTypes.func.isRequired,
  todos: PropTypes.arrayOf(PropTypes.shape({
    text: PropTypes.string.isRequired,
    completed: PropTypes.bool.isRequired
  }).isRequired).isRequired
}

当我 运行 我的应用程序。我能够将一个项目添加到待办事项列表中。但是,当点击 todoItem 时,文本消失,上面的两个警告显示在控制台中。

研究警告后。我删除了两个文本道具声明,如

TodoList.propTypes = {
  onTodoClick: PropTypes.func.isRequired,
  todos: PropTypes.arrayOf(PropTypes.shape({
    completed: PropTypes.bool.isRequired
  }).isRequired).isRequired
} 

App.propTypes = {
  visibleTodos: PropTypes.arrayOf(PropTypes.shape({
    completed: PropTypes.bool.isRequired
  }).isRequired).isRequired,
 ......
}

之后,警告消失。但是,我的 todoItem 消失了 onTodoClick。请我解决这个问题吗?任何帮助将不胜感激。

您的错误是由于没有为 todo 项生成 id。所以警告是正确的,并且正确地指出了缺少的内容。

reducers.js 中添加例如 id: Math.random(),您的警告将消失。

整个reducer函数:

function todos(state = [], action) {
  switch (action.type) {
    case ADD_TODO:
        return [
            ...state,
            {
                text: action.text,
                completed: false,
                id: Math.random()
            }
        ]
    // other cases 
  }
}

万一它对任何人有帮助...

我今天遵循的是相同的教程,运行 在这个答案中。将数字插入 ADD_TODO 可修复上述错误,但 TOGGLE_TODO 仍然无法正常工作。

我不知道这是否是世界上最好的修复方法,但当我在同一个 reducers.js 文件中向下移动几行时,我的切换工作正常,到 case TOGGLE_TODO 位,并将 state.map 函数内的 if 语句更改为:

if (todo.id === action.id) { return Object.assign... }