react-redux Виджет комментариев

176
17 августа 2021, 03:40

Я обучаюсь сейчас redux. Задача стоит в том, чтобы переписать виджет комментариев с одного react на redux. Вроде все получается, но не могу понять, как передать значение inputa в свойство name.

//action creators 
export const addComment = (name) => { 
  return { 
    type: ADD_COMMENT, 
    id: nextCommentId++, 
    name 
  } 
} 
 
export const removeComment = (id) => { 
  return { 
    type: REMOVE_COMMENT, 
    id 
  } 
}

Функция reducer

const comments = (state = [], action) => { 
  switch (action.type) { 
    case ADD_COMMENT: 
      return [ 
      ...state, 
      { 
        name: action.name, 
        id: action.id 
      } 
    ] 
    case REMOVE_COMMENT: 
      return state.filter((comment, id) => id !== action.id); 
 
    default: 
      return state 
  } 
} 
 
export default comments;

Это файл добавления комментария

import React, { Component } from 'react'; 
import { addComment } from '../actions/index.js' 
 
const AddComment = ({ addComment,name }) => { 
 
  return ( 
    <div> 
      <form> 
        <label htmlFor="username">Введите ваше имя:</label> <br /> 
        <input 
        type="text" 
        id="username" 
        onChange={ev => { 
           name: ev.target.value 
        }} 
        /> <br /><br /> 
 
        <label htmlFor="usercomment">Введите ваш комментарий:</label> <br /> 
        <textarea 
          id="usercomment" 
          rows="10" 
          cols="40" 
        ></textarea> <br /> 
      </form> 
        <button 
          className="btn" 
          onClick={ev => { 
            addComment(name); 
          }} 
        > 
          Добавить комментарий 
        </button> 
    </div> 
  ) 
} 
 
export default AddComment;

Файл со списком комментариев

import React from 'react'; 
import { removeComment }  from '../actions/index'; 
 
const CommentList = ({ comments, removeComment, name }) => { 
 
  return ( 
        <ul> 
          { 
            comments.map((comment, index) => { 
              return ( 
                <li key={index}> 
                  <b> 
                  {comment.name + ' ('  + ')'} 
                  </b> <button 
                  className="btn-remove" 
                  onClick={ev => { 
                    removeComment(index) 
                  }} 
                  > 
                  Удалить комментарий 
                  </button><br /> 
 
                  </li> 
                ) 
 
              }) 
            } 
          </ul> 
  ) 
} 
 
export default CommentList;

файл app.js

import React from 'react'; 
import { connect } from 'react-redux'; 
 
import CommentList from '../components/comment-list'; 
import AddComment from '../components/add-comments'; 
 
import { addComment,removeComment } from '../actions/index'; 
 
let App = ({ comments, addComment, removeComment }) => { 
 
  return ( 
    <div> 
      <CommentList comments={comments} removeComment={removeComment} /> 
      <AddComment addComment={addComment}/> 
    </div> 
  ) 
} 
 
const mapStateToProps = (state) => { 
  return { 
    comments: state 
  } 
} 
 
const mapDispatchToProps = (dispatch) => { 
  return { 
    addComment: (name) => dispatch(addComment(name)), 
    removeComment: (id) => dispatch(removeComment(id)) 
  } 
} 
 
 
 
App = connect( 
  mapStateToProps, 
  mapDispatchToProps 
)(App); 
 
export default App;

Задача стоит в том, чтобы передать имя, текст коммента и дату. Но для начала хочу сделать, чтобы хотяб добавлялось имя.

Answer 1

Нужно сохранять значение ипута в стейт и затем задиспатчить событие. Как-то так:

import React, { useState } from 'react';
import { connect } from 'react-redux';
import { addComment } from '../actions/index.js'
const AddComment = ({ addComment }) => {
  const [name, setName] = useState('');
  return (
    <div>
      <form>
        <label htmlFor="username">Введите ваше имя:</label> <br />
        <input
          type="text"
          id="username"
          value={name}
          onChange={ev => {
            setName(ev.target.value)
          }}
        /> <br /><br />
        <label htmlFor="usercomment">Введите ваш комментарий:</label> <br />
        <textarea
          id="usercomment"
          rows="10"
          cols="40"
        ></textarea> <br />
      </form>
      <button
        className="btn"
        onClick={ev => {
          addComment(name);
        }}
      >
        Добавить комментарий
      </button>
    </div>
  )
}
const mapDispatchToProps = {
  addComment,
}

export default connect(null, mapDispatchToProps)(AddComment)

Обратите внимание, мы оборачиваем AddComment в connect для того чтоб связать компонент с редаксом и давать редаксу знать о событии от компонента.

READ ALSO
Фильтр на React

Фильтр на React

В state массив и функция:

130
Заменить onclick на addEventListener

Заменить onclick на addEventListener

Как заменить onclick на addEventListener так, чтобы остались те же свойства? То есть после нажатия на <button id="delete">Delete</button> при нажатии на элементы...

75