React useState hook - 组件被渲染两次 [英] React useState hook - component is rendered twice

查看:52
本文介绍了React useState hook - 组件被渲染两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道为什么我的组件 SearchResults 被渲染了两次.

MainPage 组件中,我想将 offers 传递给子组件 SearchResults:

const mainPage = () =>{const [offers, setOffers] = useState(null);useEffect(() => {onInitOffers();}, [])const onInitOffers = () =>{axios.get('/提供').then(响应 => {setOffers(response.data);}).catch(错误=> {控制台日志(错误);})}常量搜索结果 = (<搜索结果searchedOffers={offers}/>);返回 (<辅助><div className={classes.container}>

{搜索结果}

</辅助>)}导出默认主页;

为什么组件 SearchResults 被渲染两次?如何使用钩子将 offers 正确传递给子组件?

在我的子组件 SearchResults 中,我必须添加 if 条件以避免错误映射不是函数:

const searchResults = props =>{useEffect(() => {console.log("渲染");console.log(props.searchedOffers) -->第一次为空}, [props.searchedOffers]);让优惠 = null;if (props.searchedOffers !== null) { -->第二次渲染后 props.searchedOffers 不为空优惠 = props.searchedOffers.map(offer => {返回 (<网格键={offer.id}><SearchResult key={offer.id} offer={offer}/></网格>)});}

解决方案

它被渲染了两次,因为当元素挂载时,你将 offers 设置为 null.如果您想确保仅在 offers 不是 null 时才呈现 SearchResults 组件,您可以执行以下操作:

返回 (<辅助><div className={classes.container}>

{优惠&&<SearchResult searchedOffers={offers}/>}

</辅助>)

如果您想非常确定 offers 是一个数组,您可以执行类似 {Array.isArray(offers) && 的操作.<SearchResult searchedOffers={offers}/>}.

通常在执行这样的异步操作时,您可能会选择实际使用三元运算符来在获取发生时显示加载指示符:

返回 (<辅助><div className={classes.container}>

{提供?<SearchResult searchedOffers={offers}/>: "加载中..."}

</辅助>)

I wonder why my component SearchResults is rendered twice.

In MainPage component I want to pass offers to child component SearchResults:

const mainPage = () => {

    const [offers, setOffers] = useState(null);

    useEffect(() => {
        onInitOffers();
    }, [])

    const onInitOffers = () => {
        axios.get('/offers')
            .then(response => {
                setOffers(response.data);
            })
            .catch(error => {
                console.log(error);
            })
    }


    const searchResults = (
        <SearchResults
            searchedOffers={offers}
        />
    );

    return (
        <Aux>
            <div className={classes.container}>
                <div className={classes.contentSection}>
                    {searchResults}
                </div>
            </div>
        </Aux>
    )
}

export default mainPage;

Why the component SearchResults is rendered twice? How to correctly pass offers to child component using hooks?

In my child component SearchResults I have to add if condition to avoid error map is not a function:

const searchResults = props => {


    useEffect(() => {
        console.log("RENDER");
        console.log(props.searchedOffers) --> null for the first time
    }, [props.searchedOffers]);

    let offers = null;
    if (props.searchedOffers !== null) { --> props.searchedOffers is not null after the second render
        offers = props.searchedOffers.map(offer => {
            return (
                <Grid key={offer.id}>
                    <SearchResult key={offer.id} offer={offer}/>
                </Grid>
            )
        });
    }

解决方案

It's rendered twice because, when the element mounts, you set offers to null. If you want to make sure you only render the SearchResults component when offers isn't null, you can do something like:

return (
  <Aux>
    <div className={classes.container}>
      <div className={classes.contentSection}>
        {offers && <SearchResult searchedOffers={offers} />}
      </div>
    </div>
  </Aux>
)

If you want to be super sure offers is an array, you can do something like {Array.isArray(offers) && <SearchResult searchedOffers={offers} />}.

Often when doing something async like this, you might elect to actually use a ternary operator to show a loading indicator while the fetch is happening:

return (
  <Aux>
    <div className={classes.container}>
      <div className={classes.contentSection}>
        {offers ? <SearchResult searchedOffers={offers} /> : "Loading..."}
      </div>
    </div>
  </Aux>
)

这篇关于React useState hook - 组件被渲染两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆