如何在不使用导出的情况下在不同组件中使用 axios 响应? [英] How do I use axios response in different components without using export?

查看:14
本文介绍了如何在不使用导出的情况下在不同组件中使用 axios 响应?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如标题所说,我希望能够对不同的组件使用相同的 axios 响应.我有一些限制,例如,我只能通过将脚本标签添加到我的 html 中来使用 react,所以像导出或 jsx 这样的东西对我来说是不可能的.

As the tittle says, I would like to be able to use the same axios response for differents components. I have some restrictions like, I'm onlyl able to use react by adding scripts tags to my html so things like exports or jsx are impossible for me.

这是我的反应代码:

    class User extends React.Component {

      state = {
        user: {}
      }

    componentWillMount() {
      console.log(localStorage.getItem("user"))
      axios.get('http://localhost:8080/dashboard?user=' + localStorage.getItem("user"))
      .then(res => {
        const userResponse = res.data
        setTimeout(() =>
       this.setState({user: userResponse.user}), 1000);
      })
    }

      render () {
        const {user} = this.state
        if (user.fullName === undefined)
        return React.createElement("div", null, 'loading..');


        return React.createElement("span", {className: "mr-2 d-none d-lg-inline text-gray-600 small" }, user.fullName);
      }

    }

    ReactDOM.render( React.createElement(User, {}, null), document.getElementById('userDropdown') );

class Roles extends React.Component{

  state = {
    user: {}
  }

  componentWillMount() {
    console.log(localStorage.getItem("user"))
    axios.get('http://localhost:8080/dashboard?user=' + localStorage.getItem("user"))
    .then(res => {
      const userResponse = res.data
      setTimeout(() =>
      this.setState({user: userResponse.user}), 1000);
    })
  }

  render () {
    const {user} = this.state
    const roles = user.user.roles.map((rol) =>  rol.roleName)

    if (user.fullName === undefined)
    return React.createElement("div", null, 'loading..');

    return React.createElement("a", {className: "dropdown-item" }, user.fullName);
  }
}


ReactDOM.render( React.createElement(Roles, {}, null), document.getElementById('dropdownRol') );

我希望能够使用相同 axios 响应的数据管理不同的组件(渲染每个组件).

I would like to be able to manage different components(rendering each one) with data of the same axios response.

考虑到我的局限性,这可能吗?

Is this possible considering my limitations?

提前致谢

推荐答案

这里有一个可行的示例,说明您可以如何执行此操作.我已尝试用评论对所有内容进行注释,但如果您有任何疑问,我很乐意尝试澄清.

Here's a working example of how you might do it. I've tried to annotate everything with comments, but I'm happy to try to clarify if you have questions.

// Fake response object for the store's "load" request
const fakeResponse = {
  user: {
    fullName: "Carolina Ponce",
    roles: [
      { roleName: "administrator" },
      { roleName: "editor" },
      { roleName: "moderator" },
      { roleName: "generally awesome person" }
    ]
  }
};

// this class is responsible for loading the data
// and making it available to other components.
// we'll create a singleton for this example, but
// it might make sense to have more than one instance
// for other use cases.
class UserStore {
  constructor() {
    // kick off the data load upon instantiation
    this.load();
  }

  // statically available singleton instance.
  // not accessed outside the UserStore class itself
  static instance = new this();

  // UserStore.connect creates a higher-order component
  // that provides a 'store' prop and automatically updates
  // the connected component when the store changes. in this
  // example the only change occurs when the data loads, but
  // it could be extended for other uses.
  static connect = function(Component) {
    // get the UserStore instance to pass as a prop
    const store = this.instance;

    // return a new higher-order component that wraps the connected one.
    return class Connected extends React.Component {
      // when the store changes just force a re-render of the component
      onStoreChange = () => this.forceUpdate();

      // listen for store changes on mount
      componentWillMount = () => store.listen(this.onStoreChange);

      // stop listening for store changes when we unmount
      componentWillUnmount = () => store.unlisten(this.onStoreChange);

      render() {
        // render the connected component with an additional 'store' prop
        return React.createElement(Component, { store });
      }
    };
  };

  // The following listen, unlisten, and onChange methods would
  // normally be achieved by having UserStore extend EventEmitter
  // instead of re-inventing it, but I wasn't sure whether EventEmitter
  // would be available to you given your build restrictions.

  // Adds a listener function to be invoked when the store changes.
  // Called by componentWillMount for connected components so they
  // get updated when data loads, etc.
  // The store just keeps a simple array of listener functions. This
  // method creates the array if it doesn't already exist, and
  // adds the new function (fn) to the array.
  listen = fn => (this.listeners = [...(this.listeners || []), fn]);

  // Remove a listener; the inverse of listen.
  // Invoked by componentWillUnmount to disconnect from the store and
  // stop receiving change notifications. We don't want to attempt to
  // update unmounted components.
  unlisten = fn => {
    // get this.listeners
    const { listeners = [] } = this;

    // delete the specified function from the array.
    // array.splice modifies the original array so we don't
    // need to reassign it to this.listeners or anything.
    listeners.splice(listeners.indexOf(fn), 1);
  };

  // Invoke all the listener functions when the store changes.
  // (onChange is invoked by the load method below)
  onChange = () => (this.listeners || []).forEach(fn => fn());

  // do whatever data loading you need to do here, then
  // invoke this.onChange to update connected components.
  async load() {
    // the loading and loaded fields aren't used by the connected
    // components in this example. just including them as food
    // for thought. components could rely on these explicit fields
    // for store status instead of pivoting on the presence of the
    // data.user object, which is what the User and Role components
    // are doing (below) in this example.
    this.loaded = false;
    this.loading = true;

    try {
      // faking the data request. wait two seconds and return our
      // hard-coded data from above.
      // (Replace this with your network fetch.)
      this.data = await new Promise(fulfill =>
        setTimeout(() => fulfill(fakeResponse), 2000)
      );

      // update the loading/loaded status fields
      this.loaded = true;
      this.loading = false;

      // call onChange to trigger component updates.
      this.onChange();
    } catch (e) {
      // If something blows up during the network request,
      // make the error available to connected components
      // as store.error so they can display an error message
      // or a retry button or whatever.
      this.error = e;
    }
  }
}

// With all the loading logic in the store, we can
// use a much simpler function component to render
// the user's name.
// (This component gets connected to the store in the
// React.createElement call below.)
function User({ store }) {
  const { data: { user } = {} } = store || {};

  return React.createElement(
    "span",
    { className: "mr-2 d-none d-lg-inline text-gray-600 small" },
    user ? user.fullName : "loading (User)…"
  );
}

ReactDOM.render(
  // Connect the User component to the store via UserStore.connect(User)
  React.createElement(UserStore.connect(User), {}, null),
  document.getElementById("userDropdown")
);

// Again, with all the data loading in the store, we can
// use a much simpler functional component to render the
// roles. (You may still need a class if you need it to do
// other stuff, but this is all we need for this example.)
function Roles({ store }) {
  // get the info from the store prop
  const { data: { user } = {}, loaded, loading, error } = store || {};

  // handle store errors
  if (error) {
    return React.createElement("div", null, "oh noes!");
  }

  // store not loaded yet?
  if (!loaded || loading) {
    return React.createElement("div", null, "loading (Roles)…");
  }

  // if we made it this far, we have user data. do your thing.
  const roles = user.roles.map(rol => rol.roleName);

  return React.createElement(
    "a",
    { className: "dropdown-item" },
    roles.join(", ")
  );
}

ReactDOM.render(
  // connect the Roles component to the store like before
  React.createElement(UserStore.connect(Roles), {}, null),
  document.getElementById("dropdownRol")
);

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="userDropdown"></div>
<div id="dropdownRol"></div>

这篇关于如何在不使用导出的情况下在不同组件中使用 axios 响应?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆