从 React 上下文 API 的列表中删除记录后无法设置道具值

Posted

技术标签:

【中文标题】从 React 上下文 API 的列表中删除记录后无法设置道具值【英文标题】:Unable to set props values after delete the record from the list in React context API 【发布时间】:2019-02-19 06:41:25 【问题描述】:

我们正在处理该项目,在该项目中我们扮演着不同的角色,例如业务、用户和组织。为此,我们为角色设置了不同的选项卡。

在单击每个选项卡时,我们要绑定组织列表,目前我们正在重复获取每个文件上的组织列表的代码,这不是最佳实践,因此我们使用了上下文 API,这将使它更多健壮,使用单个代码文件来获取组织列表。

一切正常,但是,从列表中删除组织后,我无法设置道具。代码如下:

context.js

import React from 'react';
export const Provider, Consumer = React.createContext()

List.js

import React,  Component  from "react";
import  Consumer  from '../../components/context';

export default  class List extends Component 
  state = 
    organizations: [],
  ;

  deleteOrganization(id) 
    var self = this;
    OrganizationService.deleteOrganization(id)
      .then(function(response) 
        if (response.status === 200) 
          self.handleDeleteSuccessResponse(response);
         else 
          console.log(response.data.errors)
        
      )
      .catch(function(error) 
        console.log(error.response.data.errors)
      );
  

  handleDeleteSuccessResponse(response) 
    var self = this;
    const organizations = self.state.organizations.filter(
      organization => organization.id !== self.state.alert.objectId
      );
      if (organizations.length === 0) 
        this.getOrganizations();
      
        this.props.context.updateValue(organizations); //seems like props not getting here
        self.setState(
      organizations: organizations
    );
  

  render() 
    const  organizations = this.state;
    const  match  = this.props;
    return (
      <div className="welcome-wrap">
        <h3 className="text-center">Organizations</h3>
        <hr />

        <Consumer>
          (context) => (
            <Component
               ...this.props 
              context=context
            />,
             console.log(context),
            <table className="table table-bordered">
              <thead>
                <tr>
                  <th scope="col">Name</th>
                </tr>
              </thead>
              <tbody>
                context.value.organizations.map(organization => (
                  <tr key=organization.id>
                    <td>organization.name</td>
                     <td>
                      <a
                        className="delete-btn"
                        onClick=event => this.deleteOrganization(organization.id)
                      >
                        Delete
                      </a>
                    </td>
                  </tr>
                ))
              </tbody>
            </table>
            )
          
        </Consumer>
      </div>
    );
  

用户.js

import React,  Component  from "react";
import  Provider  from './../context';

// Import helper
import 
  currentLoggedInUser,
 from "../../components/Helper";

// import service
import  OrganizationService  from "../../services/Index";

export default class User extends Component 
  constructor() 
    super()
    this.state = 
    actions: 
      getOrganizations: this.getOrganizations,
      updateValue: this.updateValue
      ,
    organizations: []
    ;
  ;
  componentWillMount()
    var id = currentLoggedInUser().belongs.id;
    this.getOrganizations(id);
  
  getOrganizations(id) 
    var self = this;
    OrganizationService.getOrganizations(id)
      .then(function(response) 
        var data = response.data;
        self.setState( organizations: data.data );
      )
      .catch(function(error) 
        console.log(error.response);
      );
  
  updateValue = (val) => 
    this.setState(organizations: val);
  
  render() 
        const  match  = this.props;
        return (
          <Provider value= value: this.state, updateValue: this.updateValue >
            <List />
        </Provider>
        );
      
    

我已经创建了上下文并在 user.js 中定义了 &lt;Provider&gt; 并在 list.js 中访问了 &lt;Consumer&gt; 以显示所有组织。

现在我删除了一些组织,它正在从数据库中删除,但是,列表没有得到更新,我可以看到旧值,一旦我刷新页面,删除的记录就会消失。

现在我想在上下文中发送更新的组织,但不获取道具。

this.props.context.updateValue(organizations);

如何设置获取上下文的道具?

我正面临从消费者状态更新到提供者状态。

【问题讨论】:

【参考方案1】:

考虑到对 deleteOrganization 函数的调用的更改,您作为上下文值传递的值或函数将仅在提供给消费者的渲染道具中可用,因此您需要将该函数作为回调传递给您的 deleteOrganization 函数并传递该函数连同下一个函数,直到你调用它。而不是调用 this.props.context.updateValue,而是调用传递的参数函数。

import React,  Component  from "react";
import  Consumer  from '../../components/context';

export default  class List extends Component 
 state = 
   organizations: [],
 ;

deleteOrganization(id, updateValueFn) 
  var self = this;
  OrganizationService.deleteOrganization(id)
  .then(function(response) 
    if (response.status === 200) 
       self.handleDeleteSuccessResponse(response, updateValueFn);
     else 
      console.log(response.data.errors)
    
  )
  .catch(function(error) 
    console.log(error.response.data.errors)
  );


handleDeleteSuccessResponse(response, updateValueFn) 
var self = this;
const organizations = self.state.organizations.filter(
  organization => organization.id !== self.state.alert.objectId
  );
  if (organizations.length === 0) 
    this.getOrganizations();
  
    updateValueFn(organizations); //seems like props not getting here
    self.setState(
  organizations: organizations
);


render() 
const  organizations = this.state;
const  match  = this.props;
return (
  <div className="welcome-wrap">
    <h3 className="text-center">Organizations</h3>
    <hr />

    <Consumer>
      (context) => (
        <Component
           ...this.props 
          context=context
        />,
         console.log(context),
        <table className="table table-bordered">
          <thead>
            <tr>
              <th scope="col">Name</th>
            </tr>
          </thead>
          <tbody>
            context.value.organizations.map(organization => (
              <tr key=organization.id>
                <td>organization.name</td>
                 <td>
                  <a
                    className="delete-btn"
                    onClick=event => this.deleteOrganization(organization.id, context.updateValue)
                  >
                    Delete
                  </a>
                </td>
              </tr>
            ))
          </tbody>
        </table>
        )
      
    </Consumer>
  </div>
);


【讨论】:

【参考方案2】:

您可以在提供者中调用作为道具传递的函数,即消费者中的updateValue,就像您使用consumer.value一样,您也可以调用consumer.updateValue(updatedValue),它将在提供者中执行updateValue

<Consumer>
 (context) => (
    <Component
     ...this.props 
    context=context
    updateValue=consumer.updateValue // e.g. passed as prop to other component which will execute this function.
        />,
    .........
    .........

    consumer.updateValue(someUpdatedValue) // e.g. values can be updated by executing the function  
    .........
    .........

  
    </Consumer>

【讨论】:

我想在道具中设置消费者对象,所以我尝试使用&lt;Component ...this.props context=context /&gt;,但是当我将 this.props 访问到 handleDeleteSuccessResponse() 方法时,没有添加我在组件中设置的上下文。所以我的问题是如何在组件中设置道具?

以上是关于从 React 上下文 API 的列表中删除记录后无法设置道具值的主要内容,如果未能解决你的问题,请参考以下文章

从核心数据中删除/添加到核心数据后,带有列表的 SwiftUI TabView 不刷新

从 React 的 Context API 组件重定向

React JS:在 API 调用成功后获取上下文数据

React Native:使用“refFromURL”从firebase中删除图像

React不会从数组中删除项目[重复]

从 REST API 填充上下文并在带有 useEffect 和 useContext 的 React 组件中使用它