【问题标题】:Result prints twice in react when using dispatch使用调度时,结果在反应中打印两次
【发布时间】:2020-08-12 19:38:15
【问题描述】:

这更像是一个好奇的问题,我觉得知道为什么会很有用,但是谁能解释为什么 console.log(recipe) 打印两次。当我单击搜索按钮时,结果会在控制台中打印两次。我想我与反应重新渲染组件两次有关,可以详细解释一下吗?

function Search(props) {
    const recipe = useSelector(state => state.recipe)
    const dispatch = useDispatch()
    const [query, setQuery] = useState("")
    
    console.log(recipe)


    const handleQuery = (event) => {
        event.preventDefault();

        console.log(`Query: ${query}`)
        dispatch(fetchRequest(query))
    }


    return (
        <form className={classes.Search} onSubmit={handleQuery}>
            <input
                className={classes.Search__field}
                placeholder="Search over 1,000,000 recipes..."
                value={query}
                onChange={(e) => setQuery(e.target.value)}
            />
            <button className={[buttonClasses.Btn, "search__btn"].join(' ')} type="submit"
            >
                <svg className={"search__icon"}>
                    <use href={magnifyingGlass + "#icon-magnifying-glass"}></use>
                </svg>
                <span>Search</span>
            </button>

           
        </form>
    );

}


export default Search;

这里是使用搜索组件的地方

import React from 'react';
import Search from './Search/Search';
import classes from './Header.module.css';
import logo from '../../img/logo.png';
import Likes from '../Header/Likes/Likes';

const header = (props) => {


    return (
        <header className={classes.Header}>
            <img src={logo} alt="Logo" className={classes.Header__logo} />
            <Search />
            <Likes />

        </header>
    )
}



export default header;

然后在 Layout 函数中使用 Header 函数 在 App.js 中

import React, { Component } from 'react';
import Aux from '../../hoc/Aux';
import classes from './Layout.module.css';
import Header from '../Header/Header';
import Results from '../Results/Results';


class Layout extends Component {

    render() {
        return (
            <Aux>
                <Header />
                <Results />
            </Aux>
        );
    }

}


export default Layout;

这里是 redux 动作

import axios from 'axios';

const FETCH_REQUEST = 'FETCH_USERS_REQUEST'

export const fetchRecipe = (recipe) => {
    return {
        type: FETCH_REQUEST,
        payload: recipe
    }
}

export const fetchRequest = (query) => {
    console.log(query)
    return (dispatch) => {
        axios(`https://forkify-api.herokuapp.com/api/search?q=${query}`)
            .then(response => {
                // console.log(response.data.recipes)
                const recipe = response.data.recipes;
                dispatch(fetchRecipe(recipe));
            })
            .catch(error => {
                console.log(error)
            })
    }
}


【问题讨论】:

  • 请说明您在应用中使用Search 组件的位置。
  • 你能把 dispatch 注释掉并观察日志是否仍然打印两次吗?
  • @Menawer 当我注释掉调度时,它什么也不做,因为没有任何动作被发送到 redux 商店。操作中正在调用异步 api 调用
  • 您是否启用了严格模式?它在新的 CRA 应用程序中默认启用并导致双重渲染。
  • documentation 可能会比我更好地解释它 - 保留它可能很有用,但有时会干扰其他软件包。创建生产版本时不会包含它。

标签: reactjs react-redux


【解决方案1】:

Ciao,我不是最擅长反应的专家,但你可以做一个测试。您知道每次重新渲染组件时都会触发 useEffect 钩子。所以你可以把你的 console.log 放在 useEffect 中,看看是否会被记录两次。比如:

useEffect(() => {
   console.log(recipe);
})

如果你有 2 个日志,那么这意味着 Search 组件被渲染了两次。否则可能与 reactjs 工作流程有关,正如我所说,我不是很专业来解释为什么会记录两次。

【讨论】:

  • 我确实使用了 useEffect,你说得对,它只打印了一次。同样正如@lawrence-witt 所暗示的那样,在我的应用程序中启用了严格模式,这导致组件呈现两次。这两种解决方案都解决了这个问题。
  • 很高兴听到这个消息。祝你有美好的一天:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多