返回

Redux教程第4部分:使用Redux数据

前端

我们已经创建了Redux store并向其中添加了数据,让我们将其用于我们的React应用程序。为此,我们首先需要创建一个名为useReduxData的自定义hook,该hook将用于访问Redux store中的数据。

import { useSelector } from 'react-redux';

const useReduxData = () => {
  const posts = useSelector((state) => state.posts);
  return posts;
};

export default useReduxData;

这个hook使用useSelector hook来访问Redux store,并返回posts的数组。我们现在可以在我们的组件中使用这个hook来获取和显示Redux store中的数据。例如,在我们的PostList组件中,我们可以使用它来显示所有post:

import useReduxData from './useReduxData';

const PostList = () => {
  const posts = useReduxData();

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
};

export default PostList;

现在,当PostList组件被渲染时,它将从Redux store中获取posts的数组,并显示所有post的标题。我们还可以使用Redux store来添加新post。为此,我们首先需要创建一个名为addPost的action:

export const addPost = (post) => {
  return {
    type: 'ADD_POST',
    post,
  };
};

这个action接受一个post对象作为参数,并将它添加到Redux store中。我们现在可以在我们的PostForm组件中使用这个action来添加新post:

import { useDispatch } from 'react-redux';
import { addPost } from './actions';

const PostForm = () => {
  const dispatch = useDispatch();

  const handleSubmit = (e) => {
    e.preventDefault();

    const title = e.target.title.value;
    const content = e.target.content.value;

    const post = {
      title,
      content,
    };

    dispatch(addPost(post));
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" name="title" placeholder="Title" />
      <textarea name="content" placeholder="Content"></textarea>
      <button type="submit">Add Post</button>
    </form>
  );
};

export default PostForm;

现在,当用户提交PostForm时,它将调用handleSubmit函数。此函数将创建一个新的post对象,并将addPost action发送到Redux store。Redux store将使用这个action将新post添加到posts的数组中。

我们还可以使用Redux store来显示单个post。为此,我们首先需要创建一个名为getPostById的selector:

export const getPostById = (id) => {
  return (state) => {
    return state.posts.find((post) => post.id === id);
  };
};

这个selector接受一个post的ID作为参数,并返回相应的post对象。我们现在可以在我们的PostDetails组件中使用这个selector来显示单个post:

import { useSelector, useDispatch } from 'react-redux';
import { getPostById } from './selectors';

const PostDetails = (props) => {
  const post = useSelector(getPostById(props.match.params.id));

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  );
};

export default PostDetails;

现在,当PostDetails组件被渲染时,它将从Redux store中获取相应post的ID,并显示post的标题和内容。我们还可以使用Redux store来编辑现有post。为此,我们首先需要创建一个名为editPost的action:

export const editPost = (post) => {
  return {
    type: 'EDIT_POST',
    post,
  };
};

这个action接受一个post对象作为参数,并将它更新到Redux store中。我们现在可以在我们的PostEditForm组件中使用这个action来编辑现有post:

import { useDispatch } from 'react-redux';
import { editPost } from './actions';

const PostEditForm = (props) => {
  const dispatch = useDispatch();

  const handleSubmit = (e) => {
    e.preventDefault();

    const title = e.target.title.value;
    const content = e.target.content.value;

    const post = {
      id: props.match.params.id,
      title,
      content,
    };

    dispatch(editPost(post));
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" name="title" placeholder="Title" />
      <textarea name="content" placeholder="Content"></textarea>
      <button type="submit">Edit Post</button>
    </form>
  );
};

export default PostEditForm;

现在,当用户提交PostEditForm时,它将调用handleSubmit函数。此函数将创建一个新的post对象,并将editPost action发送到Redux store。Redux store将使用这个action将新post更新到posts的数组中。

我们还可以使用Redux store来显示post的作者的详细信息。为此,我们首先需要创建一个名为getAuthorById的selector:

export const getAuthorById = (id) => {
  return (state) => {
    return state.authors.find((author) => author.id === id);
  };
};

这个selector接受一个作者的ID作为参数,并返回相应的作者对象。我们现在可以在我们的PostDetails组件中使用这个selector来显示post的作者的详细信息:

import { useSelector } from 'react-redux';
import { getAuthorById } from './selectors';

const PostDetails = (props) => {
  const post = useSelector(getPostById(props.match.params.id));
  const author = useSelector(getAuthorById(post.authorId));

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
      <p>Author: {author.name}</p>
    </div>
  );
};

export default PostDetails;

现在,当PostDetails组件被渲染时,它将从Redux store中获取相应post的ID和作者的ID,并显示post的标题、内容和作者的姓名。我们还可以使用Redux store来发布发布时间戳。为此,我们首先需要创建一个名为getTimestampById的selector:

export const getTimestampById = (id) => {
  return (state) => {
    return state.posts.find((post) => post.id === id).timestamp;
  };
};

这个selector接受一个post的ID作为参数,并返回相应的发布时间戳。我们现在可以在我们的PostDetails组件中使用这个selector来显示发布时间戳:

import { useSelector } from 'react-redux';
import { getTimestampById } from './selectors';

const PostDetails = (props) => {
  const post = useSelector(getPostById(props.match.params.id));
  const timestamp = useSelector(getTimestampById(post.id));

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
      <p>Author: {author.name}</p>
      <p>Timestamp: {timestamp}</p>
    </div>
  );
};

export default PostDetails;

现在,当PostDetails组件被渲染时,它将从Redux store中获取相应post的ID,并显示post的标题、内容、作者的姓名和发布时间戳。我们还可以使用Redux store来添加评价按钮。为此,我们首先需要创建一个名为addRating的action:

export const addRating = (post, rating) => {
  return {
    type: 'ADD_RATING',
    post,
    rating,
  };
};

这个action接受一个post对象和一个评价值作为参数,并将它添加到Redux store中。我们现在可以在我们的PostDetails组件中使用这个action来添加评价按钮:

import { useDispatch } from 'react-redux';
import { addRating } from './actions';

const PostDetails = (props) => {
  const dispatch = useDispatch();

  const handleRating = (e) => {
    e.preventDefault();

    const rating = e.target.rating.value;

    dispatch(addRating(post, rating));
  };

  return