通过React中的props传递用户ID

时间:2019-06-21 22:55:10

标签: reactjs

我是React的新手。我有 App.jsx

import React, { Component } from 'react';
import { Route, Switch } from 'react-router-dom';
import axios from 'axios';

import About from './components/About';
import NavBar from './components/NavBar';
import Form from './components/forms/Form';
import Logout from './components/Logout';
import UserStatus from './components/UserStatus';
import Seeds from './components/Seeds';
import Message from './components/Message';


class App extends Component {
  constructor() {
    super();
    this.state = {
      users: [],
      title: 'Project',
      isAuthenticated: false,
      messageName: null,
      messageType: null,   
    };
    this.logoutUser = this.logoutUser.bind(this);
    this.loginUser = this.loginUser.bind(this);
    this.createMessage = this.createMessage.bind(this);
    this.removeMessage = this.removeMessage.bind(this);
  };
  componentWillMount() {
    if (window.localStorage.getItem('authToken')) {
      this.setState({ isAuthenticated: true });
    };
  };
  componentDidMount() {
    this.getUsers();
  };
  getUsers() {
    axios.get(`${process.env.REACT_APP_WEB_SERVICE_URL}/users`)
    .then((res) => { this.setState({ users: res.data.data.users }); })
    .catch((err) => { });
  };
  logoutUser() {
    window.localStorage.clear();
    this.setState({ isAuthenticated: false });
  };
  loginUser(token) {
    window.localStorage.setItem('authToken', token);
    this.setState({ isAuthenticated: true });
    this.getUsers();
    this.createMessage('Welcome', 'success');
  };
  createMessage(name='Sanity Check', type='success') {
    this.setState({
      messageName: name,
      messageType: type
    });
    setTimeout(() => {
      this.removeMessage();
    }, 3000);
  };
  removeMessage() {
    this.setState({
      messageName: null,
      messageType: null
    });
  };
  render() {
    return (
      <div>
        <NavBar
          title={this.state.title}
          isAuthenticated={this.state.isAuthenticated}
        />
        <section className="section">
          <div className="container">
            {this.state.messageName && this.state.messageType &&
              <Message
                messageName={this.state.messageName}
                messageType={this.state.messageType}
                removeMessage={this.removeMessage} 
              />
            }
            <div className="columns">
              <div className="column is-half">
                <br/>
                <Switch>
                  <Route exact path='/' render={() => (
                    <SpotifyAuth
                    />
                  )} />
                  <Route exact path='/about' component={About}/>
                  <Route exact path='/register' render={() => (
                    <Form
                      formType={'Register'}
                      isAuthenticated={this.state.isAuthenticated}
                      loginUser={this.loginUser}
                      createMessage={this.createMessage} 
                    />
                  )} />
                  <Route exact path='/login' render={() => (
                    <Form
                      formType={'Login'}
                      isAuthenticated={this.state.isAuthenticated}
                      loginUser={this.loginUser}
                      createMessage={this.createMessage} 
                    />
                  )} />
                  <Route exact path='/logout' render={() => (
                    <Logout
                      logoutUser={this.logoutUser}
                      isAuthenticated={this.state.isAuthenticated}
                    />
                  )} />
                  <Route exact path='/status' render={() => (
                    <UserStatus
                      isAuthenticated={this.state.isAuthenticated}
                    />
                  )} />
                  <Route exact path='/seeds' render={() => (
                    <Seeds
                      isAuthenticated={this.state.isAuthenticated}
                    />
                  )} />
                </Switch>
              </div>
            </div>
          </div>
        </section>
      </div>
    )
  }
};

export default App;

Form.jsx 组件:

import React, { Component } from 'react';
import axios from 'axios';
import { Redirect } from 'react-router-dom';
import { registerFormRules, loginFormRules, spotifyLoginFormRules } from './form-rules.js';
import FormErrors from './FormErrors.jsx';


class Form extends Component {
  constructor (props) {
    super(props);
    this.state = {
      formData: {
        restaurant: '',
        username: '',
        email: '',
        password: ''
      },
      registerFormRules: registerFormRules,
      loginFormRules: loginFormRules,
      valid: false,
    };
    this.handleUserFormSubmit = this.handleUserFormSubmit.bind(this);

  componentDidMount() {
    this.clearForm();
  };
  componentWillReceiveProps(nextProps) {
    if (this.props.formType !== nextProps.formType) {
      this.clearForm();
    };
  };
  clearForm() {
    this.setState({
      formData: {restaurant: '', username: '', email: '', password: ''}
    });
  };
  handleFormChange(event) {
    const obj = this.state.formData;
    obj[event.target.name] = event.target.value;
    this.setState(obj);
    this.validateForm(); 
  };
  handleUserFormSubmit(event) {
    event.preventDefault();
    const formType = this.props.formType
    const data = {
      restaurant: this.state.formData.restaurant,
      email: this.state.formData.email,
      password: this.state.formData.password
    };
    if (formType === 'Register') {
      data.username = this.state.formData.username
    };
    const url = `${process.env.REACT_APP_WEB_SERVICE_URL}/auth/${formType.toLowerCase()}`;
    axios.post(url, data)
      .then((res) => {
        this.clearForm();
        this.props.loginUser(res.data.auth_token);
    })
    .catch((err) => {

      if (formType === 'Login') {
        this.props.createMessage('Login failed.', 'danger');
      };

      if (formType === 'Register') {
        this.props.createMessage('That user already exists.', 'danger');
      };
    });
  };
  allTrue() {
    let formRules = loginFormRules;
    if (this.props.formType === 'Register') {
      formRules = registerFormRules;
    }
    for (const rule of formRules) {
      if (!rule.valid) return false;
    }
    return true;
  };
  resetRules() {
    const registerFormRules = this.state.registerFormRules;
    for (const rule of registerFormRules) {
      rule.valid = false;
    }
    this.setState({registerFormRules: registerFormRules})

    const loginFormRules = this.state.loginFormRules;
    for (const rule of loginFormRules) {
      rule.valid = false;
    }
    this.setState({loginFormRules: loginFormRules})
  };
  validateEmail(email) {
    // eslint-disable-next-line
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);
  };
  render() {
    if (this.props.isAuthenticated) {
      return (<Redirect to='/' />);
    };
    let formRules = this.state.loginFormRules;  
    if (this.props.formType === 'Register') {
      formRules = this.state.registerFormRules;
    }
  return (
    <div>
      {this.props.formType === 'Login' &&
        <h1 className="title is-1">Log In</h1>
      }
      {this.props.formType === 'Register' &&
        <h1 className="title is-1">Register</h1>
      }
      <hr/><br/>
      <FormErrors
        formType={this.props.formType}
        formRules={formRules}
      />
      <form onSubmit={(event) => this.handleUserFormSubmit(event)}>
       {this.props.formType === 'Register' &&
        <div className="field">
         <input
          name="restaurant"
          className="input is-medium"
          type="text"
          placeholder="Enter your restaurant name"
          required
          value={this.state.formData.coffeeshop}
          onChange={this.handleFormChange}
        /> 
        </div>
        }
          <div className="field">
            <input
              name="username"
              className="input is-medium"
              type="text"
              placeholder="Enter a username"
              required
              value={this.state.formData.username}
              onChange={this.handleFormChange}
            />
          </div>
        <div className="field">
          <input
            name="email"
            className="input is-medium"
            type="email"
            placeholder="Enter an email address"
            required
            value={this.state.formData.email}
            onChange={this.handleFormChange}
          />
        </div>
        <div className="field">
          <input
            name="password"
            className="input is-medium"
            type="password"
            placeholder="Enter a password"
            required
            value={this.state.formData.password}
            onChange={this.handleFormChange}
          />
        </div>
        <input
          type="submit"
          className="button is-primary is-medium is-fullwidth"
          value="Submit"
          disabled={!this.state.valid}  
        />
      </form>
    </div>
    )
  };
};

export default Form;

UserStatus.jsx

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
import './css/box.css'


class UserStatus extends Component {
  constructor (props) {
    super(props);
    this.state = {
      restaurant:'',      
      email: '',
      id: '',
      username: '',
      active: '',
      admin: ''    
    };
  };
  componentDidMount() {
    if (this.props.isAuthenticated) {
      this.getUserStatus();
    }
  };
  getUserStatus(event) {
    const options = {
      url: `${process.env.REACT_APP_WEB_SERVICE_URL}/auth/status`,
      method: 'get',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${window.localStorage.authToken}`
      }
    };
    return axios(options)
    .then((res) => { 
      console.log(res.data)  
      console.log(res.data.data) 
      this.setState({
        restaurant: res.data.data.restaurant,
        email: res.data.data.email,
        id: res.data.data.id,
        username: res.data.data.username,
        active: String(res.data.data.active),
        admin: String(res.data.data.admin),
      })
    })
    .catch((error) => { console.log(error); });
  };
  render() {
    if (!this.props.isAuthenticated) {
      return (
        <p>You must be logged in to view this. Click <Link to="/login">here</Link> to log back in.</p>
      )
    };
    return (
      <div>
      <h1 className="title is-1"><font color="#C86428">Current User</font></h1>
      <hr/><br/>
      <ul>
        <li><strong><font color="#C86428">restaurant:</font></strong><font color="white"> {this.state.restaurant} </font></li>
        <li><strong><font color="#C86428">User ID:</font></strong><font color="white"> {this.state.id} </font></li>
        <li><strong><font color="#C86428">Email:</font></strong><font color="white"> {this.state.email} </font></li>
        <li><strong><font color="#C86428">Username:</font></strong><font color="white"> {this.state.username} </font></li>
        <li><strong><font color="#C86428">Active:</font></strong><font color="white"> {this.state.active} </font></li>
        <li><strong><font color="#C86428">Admin:</font></strong><font color="white"> {this.state.admin} </font></li> 
      </ul>
    </div>
    )
  };
};

export default UserStatus;

最后,这个Seeds.jsx,我需要user.id才能调用我的后端,就像这样:

import React, { Component } from 'react';
import axios from 'axios';


class Seeds extends Component{
  constructor (props) {
    super(props);
    this.state = { 
        restaurant:'',      
        email: '',
        id: '',
        username: '',
        active: '',
        admin: '',
        template:'',
      formSeeds:{
        type1:'',
        type2:'',
        type3:'',
      },
      formEditMenu:{
        item:'',
        item2:'',
        item3:'',
      }
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmitSeeds = this.handleSubmitSeeds.bind(this);
    this.handleSubmitCoffees = this.handleSubmitCoffees.bind(this);
  };
  componentDidMount() {
    if (this.props.isAuthenticated) {
      this.getSeeds();
    }
  };
  getSeeds(event) {
    const options = {
      url: `${process.env.REACT_APP_WEB_SERVICE_URL}/seeds/${this.props.getUserStatus.id}`, //HERE
      method: 'get',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${window.localStorage.authToken}`
      }
    };
    return axios(options)
    .then((res) => {
      console.log(res.data.data)
      this.setState({
        restaurant: res.data.data[0].restaurant,
        id: res.data.data[0].id,
        template: res.data.data[0].content
      })
      console.log(res.data.data[0].id);
    })    
    .catch((error) => { console.log(error); });
  };
  handleChange(event){
    const objformSeeds = this.state.formSeeds;
    objformSeeds[event.target.name] = event.target.value;
    this.setState(objformSeeds);

    const formEditMenu = this.state.formEditMenu;
    formEditMenu[event.target.name] = event.target.value;
    this.setState(formEditMenu);
    }
  handleSubmitSeeds(event) {
    event.preventDefault();
    //const formSeeds = this.props.formSeeds
    const data = {
      type1: this.state.formSeeds.type1,
      type2: this.state.formSeeds.type2,
      type3: this.state.formSeeds.type3,
    };
    const url = `${process.env.REACT_APP_WEB_SERVICE_URL}/handle_seeds`;
    axios.post(url, data)
      .then((res) => {
        console.log(data);
      })
      .catch((err) => {
      });
  };
  handleSubmitCoffees(event) {
    event.preventDefault();
    //const formEditMenu = this.props.formEditMenu
    const data = {
      item:  this.state.formEditMenu.item,
      item2: this.state.formEditMenu.item2,
      item3: this.state.formEditMenu.item3,
    };
    const url = `${process.env.REACT_APP_WEB_SERVICE_URL}/edit_menu${this.props.getUserStatus.id}`; //AND HERE
    axios.post(url, data)
      .then((res) => {
        console.log(data);
      })
      .catch((err) => {
      });
    };

    render(){

        //var seeds_page = this.state.template;
        var __html = this.state.template;
        var template = { __html: __html };

        return (
           <div id="parent">
            <div dangerouslySetInnerHTML={template}/>
              <form>
                <input type='text' name='name' onChange={this.handleChange}/><br/>
                <button type="button" onClick={this.handleSubmitCoffees} />
              </form>
          </div>
        );
    }
}

export default Seeds;

我正在尝试通过propsthis.props.getUserStatus.id)获取ID,但是我得到了undefined。如何在这里将user.id传递给Seeds.jsx组件?

2 个答案:

答案 0 :(得分:2)

好吧,首先,您可能想使用像redux这样的商店来进行状态管理。如果您确实想将状态保持在本地,则应“取消”状态,并将getUserStatus()函数移动到尽可能高的父级(在您的情况下为App.js)。然后,在App.js中,将状态设置为userStatus对象,并将其传递给需要它的所有组件。

<Route exact path='/seed' render={() => (
   <Seed
     ....
     userStatus={this.state.userStatus} 
   />
)} />

并在您的子组件中:

....
render(){
  const { userStatus } = this.props
  return(
    ......
    const url = `${process.env.REACT_APP_WEB_SERVICE_URL}/edit_menu${userStatus.id}`;


  )
}

答案 1 :(得分:0)

您传递给Seeds的唯一属性是isAuthenticated