Почему эта кнопка не отображается, когда состояние ложно? - PullRequest
1 голос
/ 30 апреля 2020

Я создал компонент, который будет функционировать как кнопка «Нравится / Не нравится». Когда состояние истинно, кнопка «Unlike» успешно отображается, но когда я нажимаю «Unlike», и она НЕ похоже успешно, состояние должно быть установлено равным false как (like: false). Тем не менее, я не вижу кнопку. Одна вещь, которую я заметил, - когда я нажимаю «Unlike», кнопка «Unlike» исчезает, а кнопка «Like» появляется на миллисекунду, а затем исчезает в воздухе. Я не могу понять, почему.

Вот все коды для моего компонента кнопки «Мне нравится»:

import React from "react";
import { API, graphqlOperation } from "aws-amplify";
import { Button } from "element-react";
import { createLike, deleteLike } from "../graphql/mutations";
import { UserContext } from "../App";

class Like extends React.Component {
  state = {
    liked: "",
  };

  componentDidMount() {
    this.setLiked();
  }

  setLiked() {
    console.log(this.props);
    const { user } = this.props;
    const { post } = this.props;
    if (post.likes.items.find((items) => items.liker === user.username)) {
      this.setState({ liked: true });
      console.log("liked: true");
    } else {
      this.setState({ liked: false });
      console.log("liked: false");
    }
  }

  handleLike = async (user) => {
    try {
      const input = {
        liker: user.username,
        likePostId: this.props.postId,
      };
      await API.graphql(graphqlOperation(createLike, { input }));
      this.setState({
        liked: true,
      });
      console.log("Liked!");
    } catch (err) {
      console.log("Failed to like", err);
    }
  };

  handleUnlike = async (likeId) => {
    try {
      const input = {
        id: likeId,
      };
      await API.graphql(graphqlOperation(deleteLike, { input }));
      this.setState({
        liked: false,
      });
      console.log("Unliked!");
    } catch (err) {
      console.log("Failed to unlike", err);
    }
  };

  render() {
    const { like } = this.props;
    const { liked } = this.state;
    return (
      <UserContext.Consumer>
        {({ user }) => (
          <React.Fragment>
            {liked ? (
              <Button type="primary" onClick={() => this.handleUnlike(like.id)}>
                Unlike
              </Button>
            ) : (
              <Button
                type="primary"
                onClick={() => this.handleLike(user, like.id)}
              >
                Like
              </Button>
            )}
          </React.Fragment>
        )}
      </UserContext.Consumer>
    );
  }
}

export default Like;

Код родительского компонента:

import React from "react";
import { API, graphqlOperation } from "aws-amplify";
import {
  onCreateComment,
  onCreateLike,
  onDeleteLike,
} from "../graphql/subscriptions";
import { getPost } from "../graphql/queries";
import Comment from "../components/Comment";
import Like from "../components/Like";
import LikeButton from "../components/LikeButton";
import { Loading, Tabs, Icon } from "element-react";
import { Link } from "react-router-dom";
import { S3Image } from "aws-amplify-react";
import NewComment from "../components/NewComment";

class PostDetailPage extends React.Component {
  state = {
    post: null,
    isLoading: true,
    isAuthor: false,
  };

  componentDidMount() {
    this.handleGetPost();
    this.createCommentListener = API.graphql(
      graphqlOperation(onCreateComment)
    ).subscribe({
      next: (commentData) => {
        const createdComment = commentData.value.data.onCreateComment;
        const prevComments = this.state.post.comments.items.filter(
          (item) => item.id !== createdComment.id
        );
        const updatedComments = [createdComment, ...prevComments];
        const post = { ...this.state.post };
        post.comments.items = updatedComments;
        this.setState({ post });
      },
    });
    this.createLikeListener = API.graphql(
      graphqlOperation(onCreateLike)
    ).subscribe({
      next: (likeData) => {
        const createdLike = likeData.value.data.onCreateLike;
        const prevLikes = this.state.post.likes.items.filter(
          (item) => item.id !== createdLike.id
        );
        const updatedLikes = [createdLike, ...prevLikes];
        const post = { ...this.state.post };
        post.likes.items = updatedLikes;
        this.setState({ post });
      },
    });
    this.deleteLikeListener = API.graphql(
      graphqlOperation(onDeleteLike)
    ).subscribe({
      next: (likeData) => {
        const deletedLike = likeData.value.data.onDeleteLike;
        const updatedLikes = this.state.post.likes.items.filter(
          (item) => item.id !== deletedLike.id
        );
        const post = { ...this.state.post };
        post.likes.items = updatedLikes;
        this.setState({ post });
      },
    });
  }

  componentWillUnmount() {
    this.createCommentListener.unsubscribe();
  }

  handleGetPost = async () => {
    const input = {
      id: this.props.postId,
    };
    const result = await API.graphql(graphqlOperation(getPost, input));
    console.log({ result });
    this.setState({ post: result.data.getPost, isLoading: false }, () => {});
  };

  checkPostAuthor = () => {
    const { user } = this.props;
    const { post } = this.state;
    if (user) {
      this.setState({ isAuthor: user.username === post.author });
    }
  };

  render() {
    const { post, isLoading } = this.state;
    return isLoading ? (
      <Loading fullscreen={true} />
    ) : (
      <React.Fragment>
        {/*Back Button */}
        <Link className="link" to="/">
          Back to Home Page
        </Link>
        {/*Post MetaData*/}
        <span className="items-center pt-2">
          <h2 className="mb-mr">{post.title}</h2>
        </span>
        <span className="items-center pt-2">{post.content}</span>
        <S3Image imgKey={post.file.key} />
        <div className="items-center pt-2">
          <span style={{ color: "var(--lightSquidInk)", paddingBottom: "1em" }}>
            <Icon name="date" className="icon" />
            {post.createdAt}
          </span>
        </div>

        <div className="items-center pt-2">
          {post.likes.items.map((like) => (
            <Like
              user={this.props.user}
              like={like}
              post={post}
              postId={this.props.postId}
            />
          ))}
        </div>
        <div className="items-center pt-2">
          {post.likes.items.length}people liked this.
        </div>
        <div>
          Add Comment
          <NewComment postId={this.props.postId} />
        </div>
        {/* Comments */}
        Comments: ({post.comments.items.length})
        <div className="comment-list">
          {post.comments.items.map((comment) => (
            <Comment comment={comment} />
          ))}
        </div>
      </React.Fragment>
    );
  }
}

export default PostDetailPage;

I кажется, я знаю, почему это не появляется. Это потому, что вначале, когда пользователю это не понравилось, нет объекта «как», поэтому показывать нечего, так как он показывается только тогда, когда ему сопоставлено «как». Я не знаю, как это исправить.

...