setState之后组件未重新呈现

时间:2020-10-05 07:55:27

标签: javascript reactjs

import Header from './components/Header';
import Bio from './components/Bio';
import styled from 'styled-components';
import Photo from './components/Photo';

class App extends Component {

  constructor(props) {
    super(props);

    this.state = {
      name: "John Smith",
      job: "Noob Developer",
      email: "John@Smith.noob",
      university: "Harvard University",
      study: "Law",
      year: "2020",
      experience: ["Google","Facebook","Airbnb"],
      input: false,
    }

    this.switchShow = this.switchShow.bind(this);
  }

  switchShow () {
    this.setState( prevState => ({
      input: !prevState.input
    }))
    console.log(this.state.input)
  }

  render() {


    let {name,job,email,university,study,year,experience,input} = this.state

    return(
      <div className="App">
      <Header/>

      

      <FlexRowContainer>
      <EditButton onClick={this.switchShow}>Edit</EditButton>
      <Photo/>
      <Bio name={name} job={job} email={email} school={university} study={study} year={year} experience={experience} input={input}>
      </Bio>
      </FlexRowContainer>

    </div>
    )
  }
}


export default App;

const FlexRowContainer = styled.div`
  display: flex;
  width: 100%;
  flex-direction: row;
  justify-content: center;
`
const EditButton = styled.button`
float: right;
width: auto;
height: auto;
position: absolute;
border: transparent;`

因此,我尝试使用switchShow方法在开关上和之后更改this.state.input,即使我在console.log(this.state.input)中成功将其从false更改为true或单击时,该组件也未呈现它再次从true变为false。有什么问题吗?

生物成分在这里

import styled from 'styled-components'

class Bio extends Component {
    constructor(props) {
        super(props)

        this.state = {
            name: this.props.name,
            job: this.props.job,
            email: this.props.email,
            school: this.props.school,
            study: this.props.study,
            yearClass: this.props.year,
            experience: this.props.experience,
            input: this.props.input,
        };

    }

    render() {

        let {name,job,email,school,study,yearClass,experience,input} = this.state


        return (
            <div>
            <StyledBioContainer>
                <StyledSubtitle>Name</StyledSubtitle>
                { !input ? <StyledParagraph>{name}</StyledParagraph> : <input></input>}
                <StyledSubtitle>Job</StyledSubtitle>
                { !input ? <StyledParagraph>{job}</StyledParagraph> : <input></input>}
                <StyledSubtitle>Email</StyledSubtitle>
                { !input ? <StyledParagraph>{email}</StyledParagraph> : <input></input>}
                <StyledSubtitle>School</StyledSubtitle>
                { !input ? <StyledParagraph>{school}</StyledParagraph> : <input></input>}
                <StyledSubtitle>Title of Study</StyledSubtitle>
                { !input? <StyledParagraph>{study}</StyledParagraph> : <input></input>}
                <StyledSubtitle>Class</StyledSubtitle>
                { !input? <StyledParagraph>{yearClass}</StyledParagraph> : <input></input>}
                <StyledSubtitle>Experiences</StyledSubtitle>
                { !input? experience.map(experience => <StyledParagraph>{experience}</StyledParagraph>) : <input></input>}
            </StyledBioContainer>
            </div>
        )
    }
}

export default Bio;


const StyledBioContainer = styled.div`
display: flex;
font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
flex-direction: column;
width: 100%;
padding: 3rem;
color: black;
height: auto;
background-color: rgba(0,105,255,.05);
text-align: center;
border-radius: 3px;
margin-top: 1.5rem;
`

const StyledSubtitle = styled.h6`
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: 12px;
margin-top: 10px;
margin-bottom: 0px;
color: gray;
`

const StyledParagraph = styled.p`
margin-top: 0.75rem;
margin-bottom: 5px;
font-size: 20px;

2 个答案:

答案 0 :(得分:0)

问题在于,在Bio组件中,您要将道具分配给构造函数中的状态变量,然后对Bio的状态进行条件渲染。创建组件时,它将获取道具并将它们分配给状态,但是当您更改道具时,将不再调用构造函数。

您可以跳过设置props的状态并在渲染器中使用props,或者如果要使用class component,可以调用componentDidUpdate并使用新的props更新状态。

这是在生物组件中使用道具代替状态进行条件渲染的有效示例

https://codesandbox.io/s/focused-rosalind-8rnih?file=/src/Bio.jsx

答案 1 :(得分:0)

问题出在您的<Bio />组件未监听道具更改以更新其内部状态的情况下。

您可以通过将其添加到<Bio />组件中来解决此问题:

componentDidUpdate(prevProps) {
    if (this.props.input !== prevProps.input)
      this.setState({input: this.props.input})
}

这是一个完整的示例:https://stackblitz.com/edit/react-vums1a?file=src/App.js

编辑:我在键入我的信息时没有看到@szczocik的答案,但是您也可以这样做,建议不要在<Bio />中使用其他状态,而应使用道具。它将获得相同的结果,但是您将丢失<Bio />的本地状态,因此它实际上取决于您是否首先需要一个状态。