我需要在我的React应用程序中获得当前用户的名称,所以我将数据从action/auth.js发送到Navbar.js,在Navbar中我得到了一个承诺,所以我用户然后获得数据。我成功地记录了数据。但我不能为了向用户展示而使用它。下面是auth.js发送数据的函数:
export const get_user_data = () => async dispatch => {
if (localStorage.getItem('access')) {
const config = {
headers: {
'Content-Type': 'application/json',
'Authorization': `JWT ${localStorage.getItem('access')}`,
'Accept': 'application/json'
}
};
try {
const res = await axios.get(`${process.env.REACT_APP_API_URL}/auth/users/me/`, config);
let name = res.data.first_name +" "+ res.data.last_name;
return name;
} catch (err) {
return err;
}
} else {
return "else accesss"
}
};
这是我的navebar。js我要在这里显示数据
import React, { Fragment } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { logout, get_user_data } from '../actions/auth';
const Navbar = ({ get_user_data,logout, isAuthenticated}) => {
console.log("get_user_data", get_user_data().then(res=>{
console.log("res", res)}));
const get_name = () => (
get_user_data().then(res=> {return res})
);
const guestLinks = () => (
<Fragment>
<li className='nav-item'>
<Link className='nav-link' to='/login'>לכניסה</Link>
</li>
<li className='nav-item'>
<Link className='nav-link' to='/signup'>להרשמה</Link>
</li>
</Fragment>
);
const authLinks = () => (
<Fragment>
<li className='nav-item'>
<a className='nav-link' href='#!' onClick={logout}>ליציאה</a>
</li>
<li className='nav-item'>
<Link className='nav-link' to='/homepage'>העסק שלי</Link>
</li>
{<li className='nav-item'>
<Link className='nav-link'>ברוך הבא {get_name()}</Link>
</li>}
</Fragment>
);
return (
<nav className='navbar navbar-expand-lg navbar-light bg-light' lang="he" dir="rtl">
<Link className='navbar-brand' to='/'>החשמלאי</Link>
<button
className='navbar-toggler'
type='button'
data-toggle='collapse'
data-target='#navbarNav'
aria-controls='navbarNav'
aria-expanded='false'
aria-label='Toggle navigation'
>
<span className='navbar-toggler-icon'></span>
</button>
<div className='collapse navbar-collapse' id='navbarNav'>
<ul className='navbar-nav'>
<li className='nav-item active'>
<Link className='nav-link' to='/'>עמוד הבית <span className='sr-only'>(current)</span></Link>
</li>
{isAuthenticated ? authLinks() : guestLinks()}
</ul>
</div>
</nav>
);
};
const mapStateToProps = state => ({
isAuthenticated: state.auth.isAuthenticated
});
export default connect(mapStateToProps, { logout, get_user_data })(Navbar);
我使用get_name()函数来解析promise中的数据,但我仍然得到promise错误。
React Error:
React -dom.development.js:13231未捕获错误:对象作为React子对象无效(found: [object Promise])。如果您打算呈现子元素的集合,请使用数组。
谢谢!
分析
您得到的行为是因为您试图显示Promise
。您需要等待Promise
被解析后才能显示它。这里我将使用useState
和useEffect
钩子来实现我所说的行为。
解决方案首先,您需要一个状态来保存userData
。从get_user_data
函数中的代码中,假设我们正在讨论的data
是用户名。此状态的默认值为空字符串。
const [name, setName] = useState('');
然后,我将创建一个useEffect
钩子来使用get_user_data
函数填充新创建的name
状态:
useEffect(() => {
get_user_data().then((data) => {
setName(data);
});
}, []);
该钩子将获取数据并在获取完成时设置name
状态。
那么我们需要在任何需要的地方使用这个name
状态。该组件的行为是,当我们获得用户名时,它将显示''
,但是一旦数据可用,UI将显示它。把这些放在一起,我们有:
import React, { Fragment, useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { logout, get_user_data } from '../actions/auth';
const Navbar = ({ get_user_data,logout, isAuthenticated}) => {
const [name, setName] = useState('');
useEffect(() => {
get_user_data().then((data) => {
setName(data);
});
}, []);
const guestLinks = () => (
<Fragment>
<li className='nav-item'>
<Link className='nav-link' to='/login'>לכניסה</Link>
</li>
<li className='nav-item'>
<Link className='nav-link' to='/signup'>להרשמה</Link>
</li>
</Fragment>
);
const authLinks = () => (
<Fragment>
<li className='nav-item'>
<a className='nav-link' href='#!' onClick={logout}>ליציאה</a>
</li>
<li className='nav-item'>
<Link className='nav-link' to='/homepage'>העסק שלי</Link>
</li>
{<li className='nav-item'>
<Link className='nav-link'>ברוך הבא {get_name()}</Link>
</li>}
</Fragment>
);
return (
<nav className='navbar navbar-expand-lg navbar-light bg-light' lang="he" dir="rtl">
<Link className='navbar-brand' to='/'>החשמלאי</Link>
<button
className='navbar-toggler'
type='button'
data-toggle='collapse'
data-target='#navbarNav'
aria-controls='navbarNav'
aria-expanded='false'
aria-label='Toggle navigation'
>
<span className='navbar-toggler-icon'></span>
</button>
<div className='collapse navbar-collapse' id='navbarNav'>
<ul className='navbar-nav'>
<li className='nav-item active'>
<Link className='nav-link' to='/'>עמוד הבית <span className='sr-only'>(current)</span></Link>
</li>
{isAuthenticated ? authLinks() : guestLinks()}
</ul>
</div>
</nav>
);
};
const mapStateToProps = state => ({
isAuthenticated: state.auth.isAuthenticated
});
export default connect(mapStateToProps, { logout, get_user_data })(Navbar);
标题>
我看到您正在使用redux和connect连接到您的状态。如果你以前使用过钩子,这段代码可能会更短更简洁:
const Navbar = () => {
const dispatch = useDispatch()
// Instead of using connect to get state, you can use the hook useSelector:
const isAuthenticated = useSelector(state => state.auth.isAuthenticated);
// No user to begin with
const [user, setUser] = useState(null);
// This will run once when the navbar renders for the first time
useEffect(() => {
get_user_data().then(fetchedUser => setUser(fetchedUser))
}, [])
function dispatchSomeAction() {
// Fire of action to redux
dispatch({ type: "logout" })
}
return (
<Fragment>
{user !== null && (<div>{user.name}</div>)}
<div>{isAuthenticated ? <p>Authenticated!</p> : <p>Not Authenticated</p>}</div>
<button onClick={dispatchSomeAction} >I will dispatch a action to redux</button>
</Fragment>
);
};
如果您正在使用redux,请参阅redux-thunk。它允许你做异步的东西,比如API调用和存储返回值在你的状态:)