Come and join us!

“The Newbies of Little Wo Shan” provides front-end developers with technical information and a series of basic articles. For a better user experience, please go to xhs-rookies.com/ to learn the latest articles.

“Code Tailor “, if you are interested in our article, or would like to make some suggestions, please follow the official account of “Rookie of Xiaohe Mountain” on wechat and contact us. You can also view our article on wechat. Every suggestion or approval is a great encouragement to us!

Actual combat case (four) : perfect message version login

We learned something new this time, and we need to change the previous version.

First we need the login page and add authentication through HOC (high-level component). Add route jump, perfect page.

Increase the routing

yarn add react-router-dom
Copy the code

Let’s add the React-router first

Modifying Route Configurations

We need to modify index.js. App.js has been the only one in the previous index.js. We add the configuration of routing to index.js.

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <Switch>
        <Route path="/login" component={Login} />
        <Route path="/home" component={App} />
        <Redirect path="/" to="/login" exact />
      </Switch>
    </BrowserRouter>
  </React.StrictMode>.document.getElementById('root'),Copy the code

By default, we have the page pointing to the Login page.

The Login page

Login Status Maintenance

If we log in successfully, we should have a place to store the information of whether the login is successful, so as to prepare for the authentication later. We use localstorage for data persistence processing.

this.props.history.replace('/home')
window.localStorage.islogin = '1'
Copy the code

Authentication jump

The React component life cycle method componentDidMount() is used to determine when the React component is loaded. For example, the componentDidMount() method is used to determine when the React component is loaded.

  componentDidMount() {
    let localStorage = window.localStorage
    if (localStorage.islogin === '1') {
      this.props.history.replace("/home")}}Copy the code

Eventually,

class Login extends PureComponent {
  componentDidMount() {
    let localStorage = window.localStorage
    if (localStorage.islogin === '1') {
      this.props.history.replace('/home')}}constructor(props) {
    super(props)
    this.state = {
      username: ' '.password: ' ',}}render() {
    return (
      <div className="login">
        <h2>Welcome to the XXX blog area</h2>
        <form className="form">
          <div className="formItem">
            <label htmlFor="username">User name:</label>
            <input
              type="text"
              id="username"
              value={this.state.username}
              onChange={(e)= > {
                this.setState({ username: e.target.value })
              }}
            />
          </div>
          <div className="formItem">
            <label htmlFor="password">Password:</label>
            <input
              type="password"
              id="password"
              value={this.state.password}
              onChange={(e)= > {
                this.setState({ password: e.target.value })
              }}
            />
          </div>
          <div
            className="loginBtn"
            onClick={()= >{this.handlelogin ()}} > Login</div>
        </form>
      </div>)}handleLogin() {
    if (this.state.username && this.state.password) {
      this.props.history.replace('/home')
      window.localStorage.islogin = '1'
      alert('welcome! ')}else {
      alert('Please enter username and password! ')}}}export default Login
Copy the code

No components required

Last time we abstracted the InputCompoent input box component and the EvaluateCompoent list display component into the Component folder, we first placed them directly in app.js.

We simply abstracts a comment component and adds our like feature to the EvaluateCompoent list presentation component, which we can like for every comment in the list.

Therefore, we changed the home page app.js to the following:

import React, { PureComponent } from 'react'
import Comment from './comment'
import './App.css'

class App extends PureComponent {
  constructor() {
    super(a)this.state = {
      title: 'Hello React'.desc: 'Did you know there was such a group? They have a dream, hard work, as a group of college students rookie, gave up the usual entertainment time, choose to learn together, grow together, the usual learning notes, summed up into the article, the purpose is very simple, I hope to help the rookie like them? Would you like to know more? Quick search wechat official account: newbies of Xiaohe Mountain, join them! '.comments: [{headPortrait: 'https://xhs-rookies.com/img/rookie-icon.png'.time: new Date(2021.4.14.21.2.30),
          nickName: 'Rookie'.detail: 'This is a team that's coming up with a series of articles, so let's look forward to their work! '.liked: true.likeNum: 23],},text: ' ',}}render() {
    const { title, desc, comments, text } = this.state
    return (
      <div className="App">
        <h2>{title}</h2>
        <div className="desc">{desc}</div>
        <div style={{ width: '100'}} % >
          <p className="commentsTitle">comments</p>
          {comments.map((item, index) => {
            return (
              <Comment
                key={item.time.getTime()}
                changeLike={()= >{ this.changeLike(index) }} {... item} /> ) })}</div>

        <div className="newComment">
          <div style={{ display: 'flex' }}>
            <img src="https://xhs-rookies.com/img/rookie-icon.png" className="" alt="" />
            <textarea value={text} onChange={(e)= >This.changetext (e)} placeholder=" please input comments "/></div>

          <div
            className="submit"
            onClick={()= >{this.addcomment ()}} > Publish</div>
        </div>
      </div>)}changeText(e) {
    this.setState({ text: e.target.value })
  }

  changeLike(index) {
    let newArray = [...this.state.comments]
    letnewItem = { ... newArray[index] }if (newItem.liked) {
      newItem.liked = false
      newItem.likeNum -= 1
    } else {
      newItem.liked = true
      newItem.likeNum += 1
    }
    newArray[index] = newItem
    this.setState({
      comments: newArray,
    })
  }

  addComment() {
    if (!this.state.text) {
      alert('Please enter message content')
      return
    }
    let detail = this.state.text
    this.setState({ text: ' ' })
    let newComment = {
      headPortrait: 'https://xhs-rookies.com/img/rookie-icon.png'.time: new Date(),
      nickName: 'Rookie',
      detail,
      liked: false.likeNum: 0,}this.setState({
      comments: [newComment, ...this.state.comments],
    })
  }
}

App.propTypes = {}

export default App
Copy the code

The home page to modify

The home page to

Here we also need authentication, that is, if you type home directly in the browser, if you are not logged in, we need to redirect it to the login login page.

Can we use the same time as login, after loading, judge and jump?

  componentDidMount() {
    let localStorage = window.localStorage
    if (localStorage.islogin === '1') {
      this.props.history.replace("/home")}}Copy the code

In fact, there is a problem here, if we jump directly after the loading is completed, whether every page should be added?

However, this authentication is a general function, if there is a profile page now, do you need such a function?

Advanced component authentication

We use higher-order components for authentication, so in the future, if each page needs to be authenticated, it only needs to be wrapped by higher-order components.

import React from 'react'
import { Redirect } from 'react-router-dom'

export default function checkRole(WrapperComponent) {
  let localStorage = window.localStorage
  return (props) = > {
    if (localStorage.islogin === '1') {
      return <WrapperComponent {. props} / >
    } else {
      return <Redirect to="/" />}}}Copy the code

Then we wrap the Home page (app.js)

export default checkRole(App)
Copy the code

Logout option

After we log in successfully, we naturally need to add the option of logging out on the main page. After logging out again, we will be authenticated to jump to the login page.

  handleLogout() {
    window.localStorage.islogin = '0'
    this.props.history.replace("/login")}Copy the code

The final home page looks like this:

import React, { PureComponent } from 'react'
import Comment from './comment'
import checkRole from './checkRole'
import './App.css'

class App extends PureComponent {
  constructor() {
    super(a)this.state = {
      title: 'Hello React'.desc: 'Did you know there was such a group? They have a dream, hard work, as a group of college students rookie, gave up the usual entertainment time, choose to learn together, grow together, the usual learning notes, summed up into the article, the purpose is very simple, I hope to help the rookie like them? Would you like to know more? Quick search wechat official account: newbies of Xiaohe Mountain, join them! '.comments: [{headPortrait: 'https://xhs-rookies.com/img/rookie-icon.png'.time: new Date(2021.4.14.21.2.30),
          nickName: 'Rookie'.detail: 'This is a team that's coming up with a series of articles, so let's look forward to their work! '.liked: true.likeNum: 23],},text: ' ',}}render() {
    const { title, desc, comments, text } = this.state
    return (
      <div className="App">
        <span
          className="logout"
          onClick={()= >{this.handlelogout ()}} > Logout</span>
        <h2>{title}</h2>
        <div className="desc">{desc}</div>
        <div style={{ width: '100'}} % >
          <p className="commentsTitle">comments</p>
          {comments.map((item, index) => {
            return (
              <Comment
                key={item.time.getTime()}
                changeLike={()= >{ this.changeLike(index) }} {... item} /> ) })}</div>

        <div className="newComment">
          <div style={{ display: 'flex' }}>
            <img src="https://xhs-rookies.com/img/rookie-icon.png" className="" alt="" />
            <textarea value={text} onChange={(e)= >This.changetext (e)} placeholder=" please input comments "/></div>

          <div
            className="submit"
            onClick={()= >{this.addcomment ()}} > Publish</div>
        </div>
      </div>)}handleLogout() {
    window.localStorage.islogin = '0'
    this.props.history.replace('/login')}changeText(e) {
    this.setState({ text: e.target.value })
  }

  changeLike(index) {
    let newArray = [...this.state.comments]
    letnewItem = { ... newArray[index] }if (newItem.liked) {
      newItem.liked = false
      newItem.likeNum -= 1
    } else {
      newItem.liked = true
      newItem.likeNum += 1
    }
    newArray[index] = newItem
    this.setState({
      comments: newArray,
    })
  }

  addComment() {
    if (!this.state.text) {
      alert('Please enter message content')
      return
    }
    let detail = this.state.text
    this.setState({ text: ' ' })
    let newComment = {
      headPortrait: 'https://xhs-rookies.com/img/rookie-icon.png'.time: new Date(),
      nickName: 'Rookie',
      detail,
      liked: false.likeNum: 0,}this.setState({
      comments: [newComment, ...this.state.comments],
    })
  }
}

App.propTypes = {}

export default checkRole(App)
Copy the code

conclusion

React is a simple example, but it covers a lot of knowledge, from HTML to scaffolding.

Home page authentication was added, PropTypes was used to check incoming data for compliance, and HOC (advanced component) was used to add common component functionality.

Instant preview

We suggest using the form of Codesanbox to quickly access the current case online.

CodeSandBox

Next day forecast

Now that we’ve learned the basics about React, in the next section we’ll move on to higher peaks — Hooks.