2017-12-10 1 views
2

Ich habe Probleme mit dem Verständnis, warum Rendering nicht auftritt, wenn Render-Funktion zur Verfügung gestellt wird, anstatt JSX direkt zurückgeben.Reagieren nicht erneut Requisiten, wenn Render-Funktion zur Verfügung gestellt wird

Hier ist mein Beispiel InputBox Komponente:

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 
} 

in diesem Fall Stadt wird jedes Mal, wenn ich redux Zustand der Stadt erneut gerendert ändern.

In diesem Beispiel wird die Stadt nur einmal übergeben und nicht neu gerendert, wenn sich der Reduxstatus ändert.

Ich möchte das letzte Beispiel verwenden, da ich die ComponentDidMount-Methode für die Initialisierung verwenden.

Ich verwende React und React-Redux in diesem Beispiel. Diese

ist, wie mein InputBox Container wie folgt aussieht:

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 
} 

EDIT:

I-Code-Snippet bin auch zu zeigen, Implementierung von createOnInputEnter Funktion

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) 
     } 
    } 
    } 
} 

Als @zarcode mit vorgeschlagen Reagieren .Component, es entspricht nicht meinen Anforderungen. Da verwende ich klassenlose Komponenten. Mehr auf Mixin Teil: https://gist.github.com/jquense/47bbd2613e0b03d7e51c

+0

Bitte fügen Sie es in https://codesandbox.io/s/new –

+0

@RIYAJKHAN https://codesandbox.io/s/8kvozyw682 –

+0

@PeterParada, wo rendert nicht –

Antwort

1

componentDidMount wird nur einmal aufgerufen und funktioniert auch in der bottom-up. So für Render in jeder Statusänderung können Sie ComponentWillReceieveprops verwenden.

+0

Das Problem mit dieser Lösung ist, dass ich auf aktualisierte Requisiten zugreifen muss.cityOnInputEnter-Funktion, die außerhalb von componentWillReceiveProps liegt. Vielleicht kann ich es falsch verstehen, können Sie mir ein demonstratives Beispiel zeigen, wie dies das Problem beim Zugriff auf aktualisierte Stadteigenschaft innerhalb der Funktion createOnInputEnter lösen kann? Ich werde Code bearbeiten, um diese Funktionsimplementierung anzuzeigen. –

+0

Auch ist es ok, dass componentDidMount nur einmal aufgerufen wird, ich benutze es nur zur Initialisierung und erwarte daher, nur einmal aufgerufen zu werden. –

1

Ihr erstes Beispiel ist eine funktionale Komponente, die Sie verwenden können, wenn Sie keine Komponentenlebenszyklusmethoden (wie componentDidMount) benötigen.

Ihr zweites Beispiel ist eine Mischung aus der funktionalen Komponente mit Lifecycle-Methoden, nicht sicher, dass es funktionieren kann, nie ausprobiert. Wenn Sie stattdessen Lebenszyklusmethoden in Ihrer Komponente verwenden möchten, würde ich vorschlagen, dass Sie eine Klassenkomponente verwenden, die React.Component erweitert. Es soll wie folgt aussehen:

... 
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

Danke für Codebeispiel, jedoch schreibe ich nicht-klasse React. Inspiriert von: https://github.com/ericelliott/react-pure-component-starter und Mixin Rezept von: https://gist.github.com/jquense/47bbd2613e0b03d7e51c. –

0

in ersten Fall const onInputEnter = createOnInputEnter({ city, setCity, setTime, getCityTime }) innerhalb der Methode der Komponente zu machen ist, da es eine funktionale Komponente ist.

Ich erhalte nicht, wie dieses Konzept arbeiten, aber für die zweite Beispiel als erstes gleich sein Sie etwas tun müssen:

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 
} 

Obwohl ich nicht sicher bin, ob dies ist der Weg, den Zugang die Requisiten drinnen rendern hier.

Verwandte Themen