【问题标题】:how to change state of a react component from another component如何从另一个组件更改反应组件的状态
【发布时间】:2020-10-12 05:47:21
【问题描述】:

我看到了几十个示例,但在我的情况下它们不起作用,我想更新“bookitem”组件中的页面变量并重新渲染它。 using 给出一个错误'期望一个赋值或函数调用,而是看到一个表达式 no-unused-expressions'

    import React from 'react'
import { Pagination, Container } from 'semantic-ui-react'
import bookitem  from './Book_item'

const PaginationI = () => (
    <Container style={{textAlign: "center", padding:'4rem'}}>
  <Pagination defaultActivePage={5} totalPages={10} onPageChange={PageChange}/>
  </Container>
)

function PageChange(event,data){
    console.log(data.activePage);
    <bookitem page={data.activePage}/>
};
export default PaginationI

/////////////////////////////////////// ///////////////////////////////////////// /////

 class bookitem extends Component{

    constructor(props){
        super (props);

        this.state={
            counter:0,
            page:0,
            data2:[]

        };
    }

    componentWillMount(){
        console.log(this.props.page)
            axios.get('/books/'+this.state.page).then(res=>{console.log(res.data);this.setState({data2:res.data});})
            console.log('aa')
            console.log(this.state.data2)


    }

    genurl(isbn){
        console.log(isbn)
    let url='http://covers.openlibrary.org/b/isbn/'+ isbn + '-L.jpg'
        return url;
    }

    render(){return(
        <div>
        <div>{this.state.page}</div>
        <Container>
        <div style={{padding:"1em 1em", textAlign: "right"}}>

        <Card.Group itemsPerRow={3} stackable={true} doubling={true}>

        {this.state.data2.map(card=>(
        <Card href="#">
    <Image src={this.genurl(card.isbn)} wrapped ui={false} />
    <Card.Content>
      <Card.Header>{card.title}</Card.Header>
      <Card.Meta>
        <span className='date'>Author:{card.author}</span>
      </Card.Meta>
      <Card.Content >
      <Rating icon='star' defaultRating={card.avgrating} maxRating={5} />
    </Card.Content>
      <Card.Description>
        {card.avgrating} Avg rating, {card.totalratings} total ratings.
      </Card.Description>
    </Card.Content>
    <Card.Content >
      <a>
        <Icon name='pencil alternate' />
        {card.reviews} Reviews
      </a>
    </Card.Content>
  </Card>
  ))}
  
  </Card.Group>
  
        </div>

        </Container>
        </div>
    )
}
}

export default bookitem

【问题讨论】:

  • 为此,您应该查看React Redux,因为它可以帮助您避免编写过于复杂的代码。
  • 对于 redux 创建了一个更精简的代码库这一事实非常同意。这里的代码有几处错误。例如PageChange函数不返回值
  • 以及来自Pagination 的属性onPageChange 建议了一个函数,该函数接受事件和可能的一些数据,但会对其进行处理。在这种情况下,它应该在当前组件中设置一个状态,然后将其作为属性放在bookitem 组件上。另请注意,JSX 中的自定义 React 组件应始终遵循 PascalCase,在这种情况下,bookitem 将不会呈现,应将其重构为 BookItem
  • 我还想强烈建议您设置一个带有 linter 的编辑器。例如,使用带有 Eslint 插件的 Visual Studio Code 来检查和格式化您的代码。它真的会极大地帮助你。如果你从npx create-react-app my-app 之类的东西开始,然后在 vs 代码中打开生成的 repo,那么上述所有内容都可以开箱即用。提升现有代码并将其转移到这个新代码库并继续工作:)
  • 我做了 Rostyslav 建议的更改,我不得不使用
    {this.props.page}
    而不是
    {this.state.page}
    和它现在正在更新元素,但“this.state.page”保持不变,因此它不会获取新书,所以我只是将分页代码放在 bookitem 中,现在它工作正常。将它们分开会很棒。谢谢大家的回答和建议。

标签: javascript reactjs


【解决方案1】:

首先 Bookitem 必须以大写字母开头。所以你必须有&lt;Bookitem/&gt;.而不是&lt;bookitem /&gt;

现在,如果您想从另一个组件更改一个反应组件的状态,您必须将一个函数从父级传递给子级,当您想要更改状态时将调用该函数。例如

const Compoent1 = () => { 
  const [state, setState] = useState(value)
  .....
  return <Component2 changeState={setState} />
}

【讨论】:

    【解决方案2】:

    问题是您根本没有渲染bookitem 组件。您必须管理 activePage 的状态,将其传递给 bookitem 并实际渲染此组件。

    import React, { useState } from "react";
    import { Pagination, Container } from "semantic-ui-react";
    import BookItem from "./Book_item";
    
    const PaginationI = () => {
      const [activePage, setActivePage] = useState(0); // manage the state of activePage
    
      function PageChange(event, data) {
        setActivePage(data.activePage); // update the state in event handler
      }
    
      return (
        <Container style={{ textAlign: "center", padding: "4rem" }}>
          <BookItem page={activePage} /> {/* render your component */}
          <Pagination
            defaultActivePage={5}
            totalPages={10}
            onPageChange={PageChange} /> {/* pass event handler */}
        </Container>
      );
    };
    
    export default PaginationI;
    

    由于与这样的 HTML 标记冲突,您还必须重命名 bookitem 组件

    import React from "react";
    
    class BookItem extends Component {
      constructor(props) {
        super(props);
    
        this.state = {
          counter: 0,
          page: 0,
          data2: [],
        };
      }
    
      componentWillMount() {
        console.log(this.props.page);
        axios.get("/books/" + this.state.page).then((res) => {
          console.log(res.data);
          this.setState({ data2: res.data });
        });
        console.log("aa");
        console.log(this.state.data2);
      }
    
      genurl(isbn) {
        console.log(isbn);
        let url = "http://covers.openlibrary.org/b/isbn/" + isbn + "-L.jpg";
        return url;
      }
    
      render() {
        return (
          <div>
            <div>{this.state.page}</div>
            <Container>
              <div style={{ padding: "1em 1em", textAlign: "right" }}>
                <Card.Group itemsPerRow={3} stackable={true} doubling={true}>
                  {this.state.data2.map((card) => (
                    <Card href="#">
                      <Image src={this.genurl(card.isbn)} wrapped ui={false} />
                      <Card.Content>
                        <Card.Header>{card.title}</Card.Header>
                        <Card.Meta>
                          <span className="date">Author:{card.author}</span>
                        </Card.Meta>
                        <Card.Content>
                          <Rating
                            icon="star"
                            defaultRating={card.avgrating}
                            maxRating={5}
                          />
                        </Card.Content>
                        <Card.Description>
                          {card.avgrating} Avg rating, {card.totalratings} total
                          ratings.
                        </Card.Description>
                      </Card.Content>
                      <Card.Content>
                        <a>
                          <Icon name="pencil alternate" />
                          {card.reviews} Reviews
                        </a>
                      </Card.Content>
                    </Card>
                  ))}
                </Card.Group>
              </div>
            </Container>
          </div>
        );
      }
    }
    
    export default BookItem;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-18
      • 2019-10-18
      • 1970-01-01
      • 1970-01-01
      • 2018-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多