繁体   English   中英

如何使用带有 React Redux 的 onChange 更新 redux 状态

[英]How to update redux state using onChange with React Redux

我正在使用 React Redux 并希望能够使用 onChange 方法更改帖子的标题和描述。 当仅使用 React 时,您这样做的方式是保留一个 useState,只要发生更改,您就会更改它,但我似乎无法让它与在 React 中使用 redux 一起工作。 而不是改变原始标题的状态,描述仍然存在并且不能改变。

从我读到的内容来看,基本的想法是在输入上有一个监听器(通常是 onChange),然后触发一个 redux 动作。 然后,您让操作告诉 reducer 对商店进行更改。

我试过这样做,但可以使其正常工作。 我做错了什么,你是如何解决的? 我还想知道如何在使用 onChange 时指定我想要更改标题或描述,或者我是否只是在每次发生更改时发送所有内容?

这是输入帖子时 redux 状态的样子:

{
  auth: {
    isSignedIn: true,
    user: {
      id: '624481f22566374c138cf974',
      username: 'obiwan',}
  },
  posts: {
    '62448632b87b223847eaafde': {
      _id: '62448632b87b223847eaafde',
      title: 'hellothere',
      desc: 'its been a long time since I heard that name...',
      username: 'vorbrodt',
      email: 'example@gmail.com',
      categories: [],
      createdAt: '2022-03-30T16:32:50.158Z',
      updatedAt: '2022-03-30T16:32:50.158Z',
      __v: 0
    }
  },
}

这是 onChange 发生的地方。 Post.js

import { getPostById, editPost } from "../actions";

const Post = ({ getPostById, editPost, username }) => {
  const [updateMode, setUpdateMode] = useState(false);
  let { id } = useParams();
  let post = useSelector((state) => state.posts[id]);


  const handleInputChange = (e) => {
    try {
      editPost(e.target.value);
    } catch (err) {}
  };

  return (
    <div className="post">
      <div className="post-wrapper">
      {updateMode ? (
        <input
          type="text"
          value={post.title}
          className="post-title-input"
          autoFocus
          onChange={(e) => handleInputChange(e)}
        />
      ) : (
        <h1 className="post-title">
          {post.title}
        </h1>
      )}
      <div className="desc-area">
        {updateMode ? (
          <textarea
            className="post-desc-input"
            value={post.desc}
            onChange={(e) => handleInputChange(e)}
          />
        ) : (
          <p className="post-desc">{post.desc}</p>
        )}
      </div>
    </div>
    </div>
  );
};

const mapStateToProps = (state) => {
  return { username: state.auth.user.username }; 
};

export default connect(mapStateToProps, { getPostById, editPost })(Post);

这是动作创建者:

//edit post in redux state
const editPost = (postValues) => (dispatch) => {
  dispatch({ type: EDIT_POST, payload: postValues });
};

这是应该改变状态的减速器。 postReducer.js

import _ from "lodash";

import { GET_POSTS, GET_POST, CREATE_POST, EDIT_POST } from "../actions/types";

function postReducer(state = {}, action) {
  switch (action.type) {
    case GET_POSTS:
      return { ...state, ..._.mapKeys(action.payload, "_id") };
    case GET_POST:
      return { ...state, [action.payload._id]: action.payload };
    case CREATE_POST:
      return { ...state, [action.payload._id]: action.payload };
    case EDIT_POST:
      //here the change should occur, not sure how to specify if title or desc should 
      //change
      return { ...state, [action.payload._id]: action.payload };
    default:
      return state;
  }
}

export default postReducer;

嘿,像这样的东西应该有帮助

const handleInputChange = (e, key, id) => {
    try {
      editPost({ [key]: e.target.value, id });
    } catch (err) {}
  };

用法

           <textarea
            className="post-desc-input"
            value={post.desc}
            onChange={(e) => handleInputChange(e, "title", post.id)}
          />

行动

const editPost = (postValues) => (dispatch) => {
  dispatch({ type: EDIT_POST, payload: postValues });
};

减速器

    case EDIT_POST:
//here we destructure the id and return the data without the id cause we //need it below
const {id, ...newData} = action.payload
const indexToUpdate = state.posts.find(post => post.id === id)
const newPostsData = [...state.posts]

//Here we update the actual object and its property that is in the state at //the specific value
newPostsData[indexToUpdate] = {...newPostData[indexToUpdate], {...newData}
          return { ...state, posts: newPostsData};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM