3

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

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

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

上下文.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 中定义<Provider>并在 list.js 中访问<Consumer>显示所有组织。

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

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

this.props.context.updateValue(organizations);

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

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

4

2 回答 2

2

考虑到对 deleteOrganization 函数的调用的更改,您作为上下文值传递的值或函数将仅在提供给使用者的渲染道具中可用,因此您需要将该函数作为回调传递给您的 deleteOrganization 函数并将该函数与 next 一起传递函数,直到你调用它。不是调用 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>
);
}
}
于 2018-09-18T06:38:59.327 回答
0

您可以调用在提供者中作为道具传递的函数,即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>
于 2018-09-14T13:09:32.393 回答