Nuru Salihu Nuru Salihu - 25 days ago 11
React JSX Question

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

Please i am trying the example Here as a react-react tutorial. The code works , however, when

onTodoClick
fails with the following error

Warning: Failed propType: Required prop
visibleTodos[0].text
was not specified in
App
. Check the render method of
Connect(App)
.


Warning: Failed propType: Required prop
todos[0].text
was not specified in
TodoList
. Check the render method of
App
.


Below is my 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)


and my 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
}


When i run my app. I was able to add a an item to the todo list. However, when click on the todoItem, The text disappear and the two warnings above shows in the console.

After studying the warnings. I removed the two text props declarations like

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


And

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


After which , the warning disappear . However , my todoItem disappear
onTodoClick
. Please ho do i addressed this ? Any help would be appreciated.

Answer

Your error is due to that no id is generated for a todo item. So the warning is correct and is telling what is missing correctly.

In reducers.js add for example id: Math.random() and your warning will dissapear.

Whole reducer function:

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