提供渲染功能时,React不重新渲染道具

问题描述 投票:2回答:3

我有理解为什么在提供渲染函数时不会发生渲染,而不是直接返回JSX。

这是我的InputBox组件的例子:

export default React => {
  const InputBox = ({ city, setCity, setTime }) => {
    const onInputEnter = createOnInputEnter({ city, setCity, setTime, getCityTime })

    return (
        <div className='InputBox'>
          <input
            defaultValue={city}
            onKeyPress={onInputEnter}
            onFocus={moveFocusAtEnd}
            autoFocus />
        </div>
      )
  }

  return InputBox
}

在这种情况下,每当我改变城市的城市时,城市就会被重新渲染。

export default React => {
  const InputBox = ({ city, setCity, setTime }) => {
    const onInputEnter = createOnInputEnter({ city, setCity, setTime, getCityTime })

    const componentDidMount = async () => {
      const { city: resultCity, time: resultTime } = await getCityTime(city)

      setCity(resultCity)
      setTime(resultTime)
    }

    const render = () => {
      return (
        <div className='InputBox'>
          <input
            defaultValue={city}
            onKeyPress={onInputEnter}
            onFocus={moveFocusAtEnd}
            autoFocus />
        </div>
      )
    }

    return { render, componentDidMount }
  }

  return InputBox
}

在此示例中,city仅传递一次,并且在redux状态更改时不会重新呈现。

我想使用后面的例子,因为我使用componentDidMount方法进行初始化。

我在这个例子中使用React和React-Redux。

这是我的InputBox容器的样子:

import createInputBox from '../components/InputBox.js'
import { connect } from 'react-redux'

...

export default React => {
  const InputBox = createInputBox(React)

  const InputBoxWithReduxStore = connect(
    ({ city }) => ({ city }),
    mapDispatchToProps
  )(InputBox)

  return InputBoxWithReduxStore
}

编辑:

我包含代码片段来显示createOnInputEnter函数的实现

function createOnInputEnter ({ city, setCity, setTime, getCityTime }) {
  return async ({ key, target }) => {
    if (key === 'Enter') {
      try {
        const inputCity = target.value

        setTime('...')

        const { city: resultCity, time: resultTime } = await getCityTime(inputCity)

        setCity(resultCity)
        setTime(resultTime)
      } catch (err) {
        const { city: resultCity, time: resultTime } = await getCityTime(city)

        setCity(resultCity)
        setTime(resultTime)
      }
    }
  }
}

正如@zarcode建议使用React.Component,它不符合我的要求。因为我使用无类组件。更多关于Mixin的部分:https://gist.github.com/jquense/47bbd2613e0b03d7e51c

javascript reactjs redux react-redux
3个回答
1
投票

componentDidMount只会调用一次,也可以自下而上调用。因此,对于每个状态更改中的渲染,您可以使用componentWillReceieveprops。


1
投票

您的第一个示例是一个功能组件,如果您不需要组件生命周期方法(如componentDidMount),则可以使用该组件。

你的第二个例子是功能组件与生命周期方法的混合,不确定它是否可行,从未尝试过。相反,如果您想在组件中使用生命周期方法,我建议您使用扩展React.Component的类组件。它应该看起来像这样:

...
import {Component} from "react";

export default class InputBox extends Component {
   onInputEnter = () => { 
       const { city, setCity, setTime } = this.props;
       createOnInputEnter({ city, setCity, setTime, getCityTime })
   }

   async componentDidMount() {
     const { city, setCity, setTime } = this.props;
     const { city: resultCity, time: resultTime } = await getCityTime(city)

     setCity(resultCity)
     setTime(resultTime)
   }

   render(){
     return (
       <div className='InputBox'>
         <input
           defaultValue={city}
           onKeyPress={onInputEnter}
           onFocus={moveFocusAtEnd}
           autoFocus />
       </div>
     )
   }

}


0
投票

在第一种情况下,const onInputEnter = createOnInputEnter({ city, setCity, setTime, getCityTime })位于组件的render方法内部,因为它是一个功能组件。

我不知道这个概念是如何工作的,但是第二个例子与第一个例子相同,你需要做这样的事情:

export default React => {
  const InputBox = ({ city, setCity, setTime }) => {

    const componentDidMount = async () => {
      const { city: resultCity, time: resultTime } = await getCityTime(city)

      setCity(resultCity)
      setTime(resultTime)
    }

    const render = () => {
    const { city, setCity, setTime } = this.props;
    const onInputEnter = createOnInputEnter({ city, setCity, setTime, getCityTime })
      return (
        <div className='InputBox'>
          <input
            defaultValue={city}
            onKeyPress={onInputEnter}
            onFocus={moveFocusAtEnd}
            autoFocus />
        </div>
      )
    }

    return { render, componentDidMount }
  }

  return InputBox
}

虽然我不确定这是否是在这里访问渲染道具的方法。

© www.soinside.com 2019 - 2024. All rights reserved.