Reactjs 在组件使用react/redux渲染之前从特定状态获取值?
我将react/redux与nodejs(express)/mongodb后端一起使用,以提供帮助 我希望在这里发生的是,如果一个用户试图去编辑一篇不属于他们的文章,我希望他们立即被重新路由,永远不会看到那个页面 比如说。用户“A”转到routeReactjs 在组件使用react/redux渲染之前从特定状态获取值?,reactjs,redux,react-redux,Reactjs,Redux,React Redux,我将react/redux与nodejs(express)/mongodb后端一起使用,以提供帮助 我希望在这里发生的是,如果一个用户试图去编辑一篇不属于他们的文章,我希望他们立即被重新路由,永远不会看到那个页面 比如说。用户“A”转到routelocalhost:8080/posts/post\u id/edit,但该帖子属于用户“B”。我希望用户A立即重新路由回该帖子或localhost:8080/posts/post\u id 在我的代码中,我可以通过一个名为getUser()的操作获取用
localhost:8080/posts/post\u id/edit
,但该帖子属于用户“B”。我希望用户A立即重新路由回该帖子或localhost:8080/posts/post\u id
在我的代码中,我可以通过一个名为getUser()的操作获取用户,该操作向后端发送一个axios.get请求,以获取当前登录的用户。我正在使用JWT令牌。不确定是否需要这些信息
下面的代码向您展示了我正在尝试做的事情
import React , { Component } from 'react';
import { bindActionCreators } from 'redux';
import * as actions from '../../actions/posts_actions';
import * as actionsIndex from '../../actions/index';
import { reduxForm, Field } from 'redux-form';
import {connect} from 'react-redux';
import {Link} from 'react-router-dom';
class EditPost extends Component {
componentWillMount() {
if(this.props.auth) {
console.log(this.props.auth); // -> returns true
this.props.getUser(); // -> this fires off
}
}
componentDidMount() {
const {id} = this.props.match.params;
this.props.getOnePost(id);
if(this.props.auth){
if(this.props.user._id !== this.props.post.author.id){
this.props.history.push(`/posts/${id}`);
}
}
}
renderField(field) {
const { meta: {touched, error} } = field;
const className = `form-group ${touched && error ? 'has-danger' : ''}`;
return (
<div className={className}>
<label><strong>{field.label}:</strong></label>
<input
className="form-control"
type={field.type}
{...field.input}
/>
<div className="text-help">
{ touched ? error : ''}
</div>
</div>
)
}
onSubmit(values) {
const {id} = this.props.match.params;
this.props.updatePost(values, id, () => {
this.props.history.push(`/posts/${id}`);
});
}
render() {
const {handleSubmit} = this.props;
const {id} = this.props.match.params;
console.log(this.props.user); // -> shows me the user after three nulls
return (
<form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
<Field
label="Title"
name="title"
type="text"
component={this.renderField}
/>
<Field
label="Content"
name="content"
type="text"
component={this.renderField}
/>
<button type="submit" className="btn btn-success">Submit</button>
<Link to={`/posts/${id}`} className="btn btn-danger">Cancel</Link>
</form>
);
}
}
function validate(values) {
const errors = {};
if(!values.title) {
errors.title = "Enter a title!";
}
if(!values.content) {
errors.content = "Enter some content please!";
}
return errors;
}
function mapStateToProps({ posts, auth, user }, ownProps) {
return {
initialValues: posts[ownProps.match.params.id],
post: posts[ownProps.match.params.id],
auth: auth.authenticated,
user: user
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({...actions, ...actionsIndex}, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(reduxForm({
validate,
form: 'editform'
})(EditPost));
import React,{Component}来自'React';
从“redux”导入{bindActionCreators};
从“../../actions/posts_actions”导入*作为操作;
从“../../actions/index”导入*作为actionsIndex;
从'redux form'导入{reduxForm,Field};
从'react redux'导入{connect};
从'react router dom'导入{Link};
类EditPost扩展组件{
组件willmount(){
if(this.props.auth){
console.log(this.props.auth);//->返回true
this.props.getUser();//->这会触发
}
}
componentDidMount(){
const{id}=this.props.match.params;
this.props.getOnePost(id);
if(this.props.auth){
if(this.props.user.\u id!==this.props.post.author.id){
this.props.history.push(`/posts/${id}`);
}
}
}
渲染场(场){
常量{meta:{toucted,error}}=field;
const className=`form group${moved&&error?'has danger':'}`;
返回(
{field.label}:
{触摸?错误:“”
)
}
onSubmit(值){
const{id}=this.props.match.params;
this.props.updatePost(值,id,()=>{
this.props.history.push(`/posts/${id}`);
});
}
render(){
const{handleSubmit}=this.props;
const{id}=this.props.match.params;
console.log(this.props.user);//->在三个空值之后显示用户
返回(
提交
取消
);
}
}
函数验证(值){
常量错误={};
如果(!values.title){
errors.title=“输入标题!”;
}
如果(!values.content){
errors.content=“请输入一些内容!”;
}
返回错误;
}
函数mapStateToProps({posts,auth,user},ownProps){
返回{
初始值:posts[ownProps.match.params.id],
post:posts[ownProps.match.params.id],
auth:auth.authenticated,
用户:用户
};
}
功能图DispatchToprops(调度){
返回bindActionCreators({…操作,…actionsIndex},分派);
}
导出默认连接(mapStateToProps、mapDispatchToProps)(reduxForm({
验证
表单:“编辑表单”
})(编辑);;
以下是console.log语句:
这里是index.js页面的编辑,有什么方法可以更新这里的用户状态吗
"use strict"
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import { applyMiddleware, createStore } from 'redux';
import reduxThunk from 'redux-thunk';
import reducers from './reducers/index';
import App from './components/app';
import '../style/style.css';
import Home from './components/pages/home';
import Header from './components/header';
import Footer from './components/footer';
import RequireAuth from './components/auth/require_auth';
import RequireUnAuth from './components/auth/require_unauth';
import Signin from './components/auth/signin';
import Signup from './components/auth/signup';
import Signout from './components/auth/signout';
import Posts from './components/pages/posts';
import {AUTH_USER} from './actions/types';
const createStoreWithMiddleware = applyMiddleware(reduxThunk)(createStore);
const store = createStoreWithMiddleware(reducers);
const token = localStorage.getItem('token');
if(token) {
store.dispatch({ type: AUTH_USER });
}
const Routes = (
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
)
ReactDOM.render(Routes, document.querySelector('.container'));
“使用严格的”
从“React”导入React;
从“react dom”导入react dom;
从'react redux'导入{Provider};
从“react router dom”导入{BrowserRouter,Route,Switch};
从“redux”导入{applyMiddleware,createStore};
从“redux thunk”导入redux thunk;
从“./reducers/index”导入减缩器;
从“./components/App”导入应用程序;
导入“../style/style.css”;
从“./components/pages/Home”导入主页;
从“./components/Header”导入标题;
从“./components/Footer”导入页脚;
从“/components/auth/require_auth”导入RequireAuth;
从“/components/auth/require_unauth”导入RequireUnAuth;
从“./components/auth/Signin”导入登录;
从“/components/auth/Signup”导入注册;
从“/components/auth/Signout”导入签出;
从“./components/pages/Posts”导入帖子;
从“./actions/types”导入{AUTH_USER};
const createStoreWithMiddleware=applyMiddleware(reduxThunk)(createStore);
const store=createStoreWithMiddleware(reducers);
const token=localStorage.getItem('token');
如果(令牌){
dispatch({type:AUTH_USER});
}
常数路由=(
)
render(Routes、document.querySelector('.container');
如果this.props.getUser()
是一个异步(thunk-ed)操作创建者,则不能保证在到达组件安装时,该操作的结果可用
在尝试访问componentDidMount
中的this.props.user
字段之前,请在其中添加空检查
你能做的就是搬家
if(this.props.user._id !== this.props.post.author.id){
this.props.history.push(`/posts/${id}`);
}
进入组件将接收道具
componentWillReceiveProps ({ user: nextUser }) {
const { history, match, user: currentUser, post } = this.props
const { id } = match.params
/* if you didn't previously have currentUser (i.e. after first load) - !currentUser
* or the user has changed - nextUser !== currentUser*/
if (!currentUser || nextUser !== currentUser) { // probably shouldn't use === here
/* the component might update before `this.props.getUser()` "returns", so make sure this is the
* update we are looking for by ensuring that we have nextUser - nextUser &&
* then get the id (nextUser._id), and run the check (!== post.author.id)*/
if (nextUser && (nextUser._id !== post.author.id)) {
history.push(`/posts/${id}`)
}
}
}
在组件上,将接收道具
-可能会清除一些问题
关于您的编辑,有几件事:
如果您有许多依赖于user
AuthComponent
HoC概念
class AuthComponent extends React.Component {
componentDidMount() {
if (!this.props.user) {
this.props.getUser()
}
}
render() {
// you could inject `user` into children here, but I would suggest that you
// instead store the result of `getUser` into a store like `redux` or `flux` and fetch from that in child components
return this.props.children
}
}
显然,您需要使用connect
并抓取user
使该组件处于非状态。你会像这样使用它
class SomeComponent extends React.Component {
render () {
return (
<AuthComponent>
<WrappedComponent/> // <- this is what's rendered
</AuthComponent>
)
}
}
就像我在评论中说的,缓存并从您的商店返回user
。。。虽然看起来你已经在这么做了
不要假设您始终可以访问用户
——请确保您正在对其进行空检查
您在组件Willmount中使用的代码不属于此处
this.props.getUser();
您最好创建一个action creator,它处理promise+异步操作,然后通过状态/分派机制返回结果,以便稍后在componentDidMount生命周期钩子中使用
Redux thunk示例调用API,请查看文档:
this.props.getUser是一个action create,它使用axios向后端发送请求,获取用户,然后通过reducer将该用户状态设置为该用户
this.props.getUser();
const store = createStore(
reducer,
applyMiddleware(thunk.withExtraArgument(api))
)
// later
function fetchUser(id) {
return (dispatch, getState, api) => {
// you can use api here
}
}
To pass multiple things, just wrap them in a single object and use destructuring:
const store = createStore(
reducer,
applyMiddleware(thunk.withExtraArgument({ api, whatever }))
)
// later
function fetchUser(id) {
return (dispatch, getState, { api, whatever }) => {
// you can use api and something else here here
}
}