Ad

React And Redux: Using State Or Refs?

I'm currently teaching my self Redux. For this purpose I created a simple Todo application. Now on this application I'm currently at the process of using dispatch() to put a todo into my store. This is a question about your opinion. I want to avoid code smell.

I found two ways of achieving this. One using state and one using ref. I was wondering which way is better? Thank you for any advice. The two versions are below.

Version one using ref:

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

class TodoList extends Component {
  taskRef = React.createRef();
  handleSubmit = event => {
    event.preventDefault();
    this.props.dispatch({
      type: ADD_TODO,
      task: this.taskRef.current.value
    });
    event.currentTarget.reset();
  };
  render() {
    let todos = this.props.todos.map((val, index) => (
      <Todo task={val.task} key={index} />
    ));
    return (
      <div>
        <form onSubmit={this.handleSubmit}>
          <label htmlFor="task">Task </label>
          <input type="text" name="task" id="task" ref={this.taskRef} />
          <button type="submit">Add a Todo!</button>
        </form>
        <ul>{todos}</ul>
      </div>
    );
  }
}

const mapDispatchToProps = state => ({
  todos: state.todos
});

export default connect(mapDispatchToProps)(TodoList);

And here is the second version using state:

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

class TodoList extends Component {
  state = {
    task: ""
  };
  handleSubmit = event => {
    event.preventDefault();
    this.props.dispatch({
      type: ADD_TODO,
      task: this.state.task
    });
    event.target.reset();
  };
  handleChange = event => {
    event.persist();
    this.setState((state, props) => ({
      [event.target.name]: event.target.value
    }));
  };
  render() {
    let todos = this.props.todos.map((val, index) => (
      <Todo task={val.task} key={index} />
    ));
    return (
      <div>
        <form onSubmit={this.handleSubmit}>
          <label htmlFor="task">Task </label>
          <input
            type="text"
            name="task"
            id="task"
            onChange={this.handleChange}
          />
          <button type="submit">Add a Todo!</button>
        </form>
        <ul>{todos}</ul>
      </div>
    );
  }
}

const mapDispatchToProps = state => ({
  todos: state.todos
});

export default connect(mapDispatchToProps)(TodoList);

EDIT: As qasimalbaqali pointed out in the comments here is a similar post on stackoverflow. I'm still unsure, because the first answer says refs are bad with reasons, the second one says React Devs say refs are awesome for grabbing values from the dom (which is what I'm doing!).

Ad

Answer

Thank you for anyone helping. It seems like a majority of the community is in favor of using state.

I also asked Dan Abramov, who said that he'd prefer a ref in this case. You can see his answer here.

Thank you everyone for your input and advice! :)

Ad
source: stackoverflow.com
Ad