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

Unable to set props values after delete the record from the list in React context API

我们正在处理这个项目,在这个项目中我们扮演着不同的角色,如业务、用户、组织。为此,我们为角色设置了不同的标签。

在单击我们想要绑定组织列表的每个选项卡时,目前我们在每个文件上重复获取组织列表的代码,这不是最佳实践,因此我们使用了上下文 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>
    );
  }
}

User.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 中定义了 <Provider>,并在 list.js 中访问了 <Consumer>,这显示了所有组织。

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

现在我想在上下文中发送更新的组织,但没有得到道具。

this.props.context.updateValue(organizations);

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

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

您可以在提供者中调用作为 props 传递的函数,即在消费者中调用 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>

考虑调用 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>
);
}
}