繁体   English   中英

如何在不刷新页面的情况下更新列表

[英]How to update list without refreshing the page

我有一个 API,它为我提供了具有以下属性的对象:id、title、url、thumbnailUrl。

我有一个模块负责具有以下代码的卡:

export interface Manual {
  id?: string | number;
  url: string;
  title: string;
  thumbnail?: string | null;
}

我有一个模块负责创建实际的 HelpCard 组件,它的代码如下:

interface Props {
  card: Manual;
  deleteProduct: Function;
  editProduct: Function;
  type: "videos" | "manuals";
}

interface State {
  editedCard: Manual;
  imageLoading?: boolean;
  tooManyRequests?: boolean;
}

export default class HelpCard extends Component<Props, State> {
  state = {
    editedCard: {
      id: -1,
      url: "",
      title: "",
      thumbnail: ""
    },
    imageLoading: true,
    tooManyRequests: false
  };

  componentDidMount() {}

  onEditClick = (card: Manual): void => {
    this.setState({ editedCard: card });
  };

  updateEditCard = (event: React.FormEvent<HTMLInputElement>, key: "url" | "title" | "thumbnail"): void => {
    const value = event.currentTarget.value;
    this.setState((prevState: State) => {
      return { editedCard: { ...prevState.editedCard, [key]: value } };
    });
  };

  render() {
    const { card } = this.props;
    const { editedCard } = this.state;
    return (
      <React.Fragment>
        <div className="card">
          <div className="card-img">
            {this.state.imageLoading ? <img src={placeholder} style={{ width: "100%", height: "100%" }}></img> : null}
            <img
              className="cardImage"
              style={
                this.state.tooManyRequests
                  ? { display: "none" }
                  : this.state.imageLoading
                  ? { display: "null" }
                  : { display: "block" }
              }
              onLoad={() => this.setState({ imageLoading: false })}
              onError={() => this.setState({ tooManyRequests: true })}
              src={card.thumbnail ? card.thumbnail : placeholder}
            />
          </div>

          <div className="card-body">
            <div style={{ textAlign: "center" }}>
              <span className="card-title">{card.title}</span>
              <hr></hr>
            </div>
            <div className="card-buttons">
              <div className="group">
                <Modal
                  trigger={
                    <Button
                      onClick={() => this.onEditClick(card)}
                      style={{ width: "90px" }}
                      icon="mode_edit"
                      className="btn blue-outline"
                      href="#!">
                      Edit
                    </Button>
                  }>
                  <form
                    onSubmit={(e) => e.preventDefault()}
                    id="videoCardEdit"
                    style={{ width: "auto", height: "auto" }}>
                    <div>
                      <div>
                        <label>Title:</label>
                        <input
                          className="input"
                          style={{ width: "100%" }}
                          name="videoCardTitle"
                          onChange={(e: React.FormEvent<HTMLInputElement>) => this.updateEditCard(e, "title")}
                          value={editedCard.title}></input>
                      </div>
                      <div>
                        <label>URL:</label>
                        <input
                          className="input"
                          style={{ width: "100%" }}
                          name="videoCardURL"
                          onChange={(e: React.FormEvent<HTMLInputElement>) => this.updateEditCard(e, "url")}
                          value={editedCard.url}></input>
                      </div>
                      <div>
                        <label>Thumbnail URL:</label>
                        <input
                          className="input"
                          style={{ width: "100%" }}
                          name="videoCardThumbnail"
                          onChange={(e: React.FormEvent<HTMLInputElement>) => this.updateEditCard(e, "thumbnail")}
                          value={editedCard.thumbnail}></input>
                      </div>
                      <br></br>
                    </div>
                    <Button
                      type="submit"
                      className="btn green-outline"
                      icon="check"
                      length="fullwidth"
                      style={{
                        float: "left"
                      }}
                      onClick={() =>
                        this.props.editProduct(
                          card.id,
                          editedCard.title,
                          editedCard.url,
                          editedCard.thumbnail,
                          this.props.type
                        )
                      }>
                      confirm
                    </Button>
                    <br></br>
                  </form>
                </Modal>
                <Button
                  icon="delete"
                  style={{ width: "90px" }}
                  onClick={() => this.props.deleteProduct(card.id, this.props.type)}
                  className="btn red-outline">
                  Delete
                </Button>
              </div>
            </div>
          </div>
        </div>
      </React.Fragment>
    );
  }
}

然后卡片会显示在 HelpList 组件上,代码如下:

export default class HelpList extends Component<Props, State> {
  state = {};

  async componentDidMount() {}

  render() {
    console.log(this.props.data);

    return (
      <div className="row">
        {this.props.data.map((card: Manual) => (
          <HelpCard
            card={card}
            key={card.id}
            deleteProduct={this.props.onDelete}
            editProduct={this.props.onEdit}
            type={this.props.type}
          />
        ))}
      </div>
    );
  }
}

在加载我的卡片的 HelpAdmin.view.tsx 模块上显示的最终列表,并具有所有 API 功能,例如我的创建/删除/编辑调用。

state和负载function如下:

export class HelpAdminView extends Component<Props, State> {
  state = {
    title: "",
    thumbnail: "",
    url: "",
    error: null,
    isEditProduct: true,
    isAddProduct: true,
    whichRadioSelected: "video",
    videos: [],
    manuals: []
  };
  componentDidMount() {
    this.loadAdminHelpCard("videos");
    this.loadAdminHelpCard("manuals");
  }

  loadAdminHelpCard = (type: "videos" | "manuals"): void => {
    const url = `${BASE_API_URL}/${type}`;
    axios
      .get(url)
      .then((res) => {
        this.setState({ [type]: res.data } as any);
      })
      .catch(function(error) {
        // handle error
        console.log(error);
      });
  };

最后,我的编辑 function 是这样的:

editProduct = (id: any, title: string, url: string, thumbnail: string, type: "videos" | "manuals") => {
    const apiUrl = `${BASE_API_URL}/${type}/${id}`;

    axios
      .put(apiUrl, {
        title: title,
        url: url,
        thumbnail: thumbnail
      })
      .then((response: any) => {
        // ? UPDATE the list with new card information here
      })
      .catch(function(error) {
        console.log(error);
      });
  };

当用户点击“编辑”时,卡片从道具中复制并放入 state。 现在只编辑卡的state。 (this.state.editedCard)当用户单击提交时,editedCard 的详细信息将提供给 editProduct(id、标题、缩略图等...)。 在 HelpAdmin.view.tsx 中,正在调用 API,这将使用新卡详细信息更改数据库。

我想弄清楚的是如何在视频/手册中更新我们的卡片,以便它反映在 UI 中。 (ON 成功调用 API)

提前感谢您的阅读和帮助!

当更新操作结束时,您可以获得当前数据。

.then((response: any) => {
    //here get the recent data from your api
    // ? UPDATE the list with new card information here
    this.loadAdminHelpCard("videos");
    this.loadAdminHelpCard("manuals");
  })

所以这会更新 state,导致父组件重新渲染,子组件也会重新渲染,所以你的 Card 组件会得到新的数据。

全部编辑产品 function:

  editProduct = (id: any, title: string, url: string, thumbnail: string, type: "videos" | "manuals") => {
    const apiUrl = `${BASE_API_URL}/${type}/${id}`;

    axios
      .put(apiUrl, {
        title: title,
        url: url,
        thumbnail: thumbnail
      })
      .then((response: any) => {
        //here get the recent data from your api
        // ? UPDATE the list with new card information here
        this.loadAdminHelpCard("videos");
        this.loadAdminHelpCard("manuals");
      })
      .catch(function(error) {
        console.log(error);
      });
  };

暂无
暂无

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

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