GithubHelp home page GithubHelp logo

redux-index-codealong's Introduction

Displaying a List of items with Redux

Introduction

With this lesson we'll finish up what we worked on the in the forms code-along by displaying our list of todos. By the end of this lesson, you will be able to:

  • Display a list of elements from our Redux store

Goal

Our state is properly updating but we are not displaying these updates to the user. We need a component that references the store and then uses the data from the store to render the list of Todos.

Displaying todos

The CreateTodo component is handling the creation side of things, so let's make a new component where we'll be getting todos from the store. We'll call this TodosContainer and connect it to Redux.

// ./src/components/todos/TodosContainer.js

import React, { Component } from "react";
import { connect } from "react-redux";

class TodosContainer extends Component {

  render() {
    return(
      <ol></ol>
    );
  }
};

export default connect()(TodosContainer);

Next we need to get the list of todos from our Redux state, so we'll need to write out a mapStateToProps() function and include it as an argument for connect():

...
const mapStateToProps = state => {
  return {
    todos: state.todos
  }
}

export default connect(mapStateToProps)(TodosContainer);

We can confirm this is working by adding a log in the render of TodosContainer. We have already imported and rendered the TodosContainer in our App component.

Now that we have a way to get data from Redux, we can create a presentational component to handle displaying our todos.

Creating a Presentational Todo Component

To start, we'll have each todo rendered as a list item. Open the Todo.js file which is inside the ./src/components/todos folder. Inside it, let's write a functional component that returns an li displaying props:

// ./src/components/todos/Todo.js

import React from "react";

const Todo = props => {
  return (
    <li>{props.text}</li>
  );
};

export default Todo;

Then, in our TodosContainer component, we'll import our Todo component, then map through the list of todos we're getting from state and render the Todo component for each of them:

// ./src/components/todos/TodosContainer.js

import React, { Component } from "react";
import { connect } from "react-redux";
import Todo from "./Todo";

class TodosContainer extends Component {

  renderTodos = () => this.props.todos.map((todo, id) => <Todo key={id} text={todo} />)

  render() {
    return(
      <ol>
        {this.renderTodos()}
      </ol>
    );
  }
};

const mapStateToProps = state => {
  return {
    todos: state.todos
  }
}

export default connect(mapStateToProps)(TodosContainer);

Now our TodosContainer is mapping over the todos it received from Redux, and passing the value of each todo into a child component, Todo. Todo in this case doesn't have any Redux related code, and is a regular, functional component.

Cleanup Todo Input

Currently when we enter a todo and click Submit, the text we entered remains in the input field; let's fix that. We can do that inside our handleSubmit function. We can reset the component's state each time the submit button is clicked by changing our function to the following:

// ./src/components/todos/CreateTodo.js

...

handleSubmit = event => {
  event.preventDefault();
  this.props.addTodo(this.state)
  this.setState({
    text: "",
  })
}


...

This will cause the page to rerender, and update the value attribute of our input field, clearing out the contents.

That's it! We've got a working app that takes in form data and displays it in a list.

Summary

We now have a fully functioning todo application. In the previous lesson, we built our CreateTodo component, which contains a simple form for adding a todo. We made it a controlled form by creating component state and writing an onChange handler that updates the component's state as the user types in their todo. We also wired the text in the component state to the input field by setting its value attribute to this.state.text.

Next, we connected our CreateTodo component to Redux, using the connect function. We created a mapDispatchToProps function to provide an addTodo function to our component. The addTodo takes the form data as an argument, creates the action object and dispatches it to the reducer. We then created an onSubmit handler that calls addTodo when the form is submitted, passing in the component state as an argument.

Finally, we built our reducer to take the action and concat the new todo into our Redux state.

Then, in this lesson, we got our Todos component working simply by accessing the state from the store, and then iterating through the list of todos and rendering the Todo component for each one.

Resources

redux-index-codealong's People

Contributors

crwhitesides avatar dependabot[bot] avatar gj avatar ihollander avatar jeffkatzy avatar lizbur10 avatar lukeghenco avatar maxwellbenton avatar rrcobb avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

redux-index-codealong's Issues

we can create

Need to add the letter c to change "an" to "can" in the sentence below:
"Now that we have a way to get data from Redux, we an create a presentational component to handle displaying our todos."

Thank you.

Codealong Uses Index as Key

Hi!

Quick note, since it's come up a lot during the React lectures, this codealong uses Todos' index as a key in:

renderTodos = () => this.props.todos.map((todo, id) => <Todo key={id} text={todo} />)

Recommend finding a way to add an id property to todo or just using the text as a key here, as in every lecture and code review the lead instructors and coaches are being very explicit about not using the index as a key value because of the problems it can cause with React caching arrays of components

Rendering Todo component as simple component

In the code along we are instructed to render the Todo component like this:
renderTodos = () => this.props.todos.map((todo, id) => <Todo key={id} text={todo} />)

I've tried rendering a simple component this way a few times and it has been unsuccessful for me. The way that I've gotten it to render is by actually invoking Todo(props).
renderTodos = () => this.props.todos.map((todo) => Todo(todo))

My repo is at: https://github.com/msteele96/redux-index-codealong-online-web-sp-000

I'd love to hear if this is a legitimate problem with rendering or if there is some other error in my code that forced me to find this workaround.

Instructions tell us to do something that's already done...

We can confirm this is working by adding a log in the render of TodosContainer and then adding TodosContainer to our App component so it will be rendered.

That's already in the app, so I submit:

We can confirm this is working by adding a log in the render of TodosContainer, or by adding some text content to the currently-empty div. Since we've already added TodosContainer to our App component, it will be rendered right away.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.