如何在不使用导出的情况下在不同组件中使用axios响应? [英] How do I use axios response in different components without using export?
问题描述
正如标题所说,我希望能够对不同的组件使用相同的axios响应. 我有一些限制,例如,我只能通过在HTML脚本中添加脚本标签来使用react,所以对我来说,export或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屋!