javascript - React problem, I don't know how to get the title...
漂亮男人
漂亮男人 2017-06-26 10:53:38
0
3
688

Let me describe the cause of the problem in detail.
There are now three components (tentatively a, b, c) to implement a user authentication function.
The a component is the parent component (compared to b and c, there is a parent component outside the a component). It is responsible for receiving the user's authentication information passed from the parent component. The b component is where the user fills in the information. The c component represents the user. Certification status (not certified, audited, certified, certification failed, corresponding statuses are 0, 1, 2, -1 respectively).
If user authentication fails, there will be a button inside component c to allow the user to re-authenticate (switch components b and c).

This is what I thought when I first wrote it:
Extract a state into the a component (tentatively show). The value of show is determined based on the authentication status (props) passed down by the a component. Through show to change which component should be displayed.
When user authentication fails, click "Re-authentication" in component c, change the status of the parent component show through the callback function, and complete the switch between components b and c.
The problem occurs in this show (tentatively true displays component b and false displays component c). The default value of show is true (allowing the user to enter information).
I change the state of show in componentWillReceiveProps of component a (didMount cannot get props, and state cannot be manipulated in render).
Now, regardless of whether the user is authenticated or not, component b is displayed by default when component a is loaded, because componentWillReceiveProps has not been called. The c component will not be displayed until the page is refreshed.
The solution I can think of now is to let the a component get the data and then determine the status of the show. I would like to ask you all, is there a better way to help me achieve this function?

Please add a picture to see clearly

漂亮男人
漂亮男人

reply all(3)
巴扎黑

a:

//构造器内
this.state = {
    show:true
}
//class内
changeState(){
    this.setState({show:false})
}
//render内
const c_props = {changeState}
<C {...c_props}/>

c:

onclick(){
    this.props.changeState();
}
仅有的幸福

There should be a component to decide whether to perform user authentication. If you want the login component to take over all this logic, then you need a loading state. It will be loading at the beginning and nothing will be displayed. The so-called loading is to decide whether to authenticate (send API request, etc.). After loading, you can decide whether to authenticate.

didMount can’t get props

I 100% guarantee that componentDidMount() can get the props parameters through this.props, but componentDidMount() is only called once when the component is created. Normally, if you want to load data, it is executed in componentDidMount() .

Peter_Zhu

Why does show need to be the state of component a? You can just treat show as a local variable in the render function.

Assume that the authentication state variable passed by the a component from props is named auth. Your a component render method can be written like this:

class A extends Component {
  render () {
    let show = this.props.auth === 2; // 0 1 2 -1
    return (
      <p>
          {show && <p>component B</p>}
          {!show && <p>component C</p>}
      </p>
    );
  }
}

========== Update =========

This is the first time I didn’t see that your C component actually has a callback arrow to change the show of A component!

Yes, this step is also a wrong design.

The authentication information obtained by component A is passed down from the parent component of component A. Then this show should only rely on this information. Component C has the function of changing this authentication information. Then, component A is obliged to change this information. Notify the parent component of the A component of the change, instead of quietly changing the state of your own component, that is, the show state you set here, just hastily. Just imagine, at this time, the props received by component A are authentication failures, and component C is rendered. Component C has the function of re-authentication. The user re-authentication is successful, and component C notifies component A that the authentication is successful. Who should component A trust at this time? Props and state are out of sync! What's even worse is the parent component of component A. He foolishly thought that he got the correct information, and told component A through props that the user authentication failed. Little did he know that component A had colluded with his subordinates and leaked all the authentication information. Changed it! If component A has a brother called component A2 at this time, and A2 also receives authentication information from their common parent component through props, then A and a bunch of guys below will quietly re-authenticate, while A's father and brother are still in the dark. Unexpectedly, the page display is inconsistent!

The correct design is that after component A receives the event notification of successful re-authentication of component C, it needs to pass this notification upwards and tell the parent component of component A. The parent component receives this event, changes its own status, and then Change the props passed to the A component, and the A component props change, causing the A component to be redrawn, thereby replacing C with B.

Only one copy of the authentication information can be saved. In your example, the authentication information is placed in the parent component of component A. Therefore, modifying the authentication information should also be done in the parent component of component A. Therefore, this show is actually just an intermediate variable generated based on props, and there is no need to design it as the state of A.

If you use redux, you won’t have this problem.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template