2017-12-12 6 views
0

Ich habe eine Funktion reagieren, um eine Form zu handhabensetState Aktualisierung Zustand aber nicht rerender

handleSubmit(e){ 
    this.setState({size: this.state.value}); 
    this.setState({maze : <Maze size={this.state.value}></Maze>},() => this.forceUpdate()); 
    console.log('set state finished'); 
    e.preventDefault(); 
    } 

in der App-Klasse vor, die die folgenden

render() { 
    return (
     <div className="App"> 
     <form onSubmit={this.handleSubmit}> 
      <label>Size: </label> 
      <input type="number" min="3" step="1" onChange={this.handleChange} value={this.state.value}></input> 
      <input type="submit" value="Generate Maze"></input> 
     </form> 
     {this.state.maze} 
     </div> 
    ); 
    } 

hat noch der Code nicht das Labyrinth nicht rerender; 2 Dinge

ich eine Benachrichtigung in der setState Rückruf beachten setzen und es tauchte (das heißt, ich nehme an, dass setState fertig und es sollte eine rerender gewesen) ohne rerender

die Kraft zu aktualisieren und übergeben Callback funktioniert nicht

Wie würde ich das beheben?

komplette Code der Hauptklasse

class App extends Component { 
    constructor(props){ 
    super(props); 
    this.state = { 
     size : 20, 
     value : 20, 
     showMaze : false 
    }; 
    this.handleChange = this.handleChange.bind(this); 
    this.handleSubmit = this.handleSubmit.bind(this); 
    } 

    componentDidMount(){ 
    this.setState({maze : <Maze size={this.state.size}></Maze>}); 
    } 

    handleChange(e){ 
    this.setState({value : e.target.value}); 
    } 

    handleSubmit(e){ 
    this.setState({size: this.state.value}); 
    this.setState({showMaze: false}); 
    this.setState({maze : <Maze size={this.state.value}></Maze>},() => this.forceUpdate()); 
    this.setState({showMaze: true}); 
    e.preventDefault(); 
    } 

    render() { 
    return (
     <div className="App"> 
     <form onSubmit={this.handleSubmit}> 
      <label>Size: </label> 
      <input type="number" min="3" step="1" onChange={this.handleChange} value={this.state.value}></input> 
      <input type="submit" value="Generate Maze"></input> 
     </form> 
     {this.state.showMaze? this.state.maze : null} 
     </div> 
    ); 
    } 
} 

komplette Code des Maze-Klasse (abzüglich der Erzeugungsalgorithmus)

class Maze extends Component{ 
    constructor(props){ 
    super(props); 
    this.state = { 
     size : this.props.size, 
     maze : null 
    }; //declare the maze null for now 
    } 

    componentDidMount(){ 
    this.generateMazev2(this.props.size); 
    } 

    generateMazev2 (size){ 
    //snippped 
    } 

    render(){ 
    var renderMaze = new Array(); //store the table 
    //calculate the percentage size of each Cell 
    var size = 80.0/this.props.size; //the table should ideally take up 80% of the page 
    if(this.state.maze !== null){ 
     this.state.maze.forEach(function (row, index, arr){ 
     var newRow = new Array(); 
     row.forEach(function (box, theIndex, arr){ 
      newRow[theIndex] = <Cell size={size} top={box.top} bottom={box.bottom} right={box.right} left={box.left}></Cell>; 
     }); 
     renderMaze[index] = <tr>{newRow}</tr>; 
     }); 
     return (<table>{renderMaze}</table>); 
    }else{ 
     return (<p>Generating</p>); 
    } 


    } 
} 

Antwort

0

Eine Sache, die Sie tun können, ist die, wie unten() -Methode machen Ändern .

render() { 
return (
    <div className="App"> 
    <form onSubmit={this.handleSubmit}> 
     <label>Size: </label> 
     <input type="number" min="3" step="1" onChange={this.handleChange} value={this.state.value}></input> 
     <input type="submit" value="Generate Maze"></input> 
    </form> 
    {this.state.showMaze? <Maze size={this.state.value}></Maze> : null} 
    </div> 
); 
} 

Danach ändern handleSubmit() -Methode wie unten

handleSubmit(e){ 
    this.setState({size: this.state.value, showMaze: true}); 
    console.log('set state finished'); 
    e.preventDefault(); 
    } 

UPDATE

Es ist keine gute Praxis, die Komponenten wie Körpereigenschaften zu halten. Ersetzen Sie daher die Zeile {this.state.showMaze? this.state.maze : null} in der Rendermethode, wie ich gezeigt habe.

Des Weiteren müssen Sie die Methode componentWillReceiveProps() in der Maze-Komponente implementieren und den Status entsprechend neuer Requisiten ändern.

componentWillReceiveProps(nextProps) { 
    this.setState({size: nextProps.size}) 
} 
+0

Versuchte es, keine Wirkung –

+0

können Sie den vollständigen Code Ihrer Komponente posten? –

+0

Der Frage –

0

Dies ist nicht der richtige Weg, UI-Komponente sollte nicht in State-Wert gespeichert werden. State sollte nur die Daten enthalten.

Lösung:

einen bool in Zustandsvariablen Pflegen und dass bool für bedingte Wiedergabe von Maze-Komponente verwenden, Anfangswert von bool wird falsch sein und die im Inneren bool handleSubmit Funktion aktualisieren.

So:

handleSubmit(e){ 
    e.preventDefault(); 
    this.setState({size: this.state.value, showMazeCom: true}); 
} 

render() { 
    return (
    <div className="App"> 
     <form onSubmit={this.handleSubmit}> 
     <label>Size: </label> 
     <input type="number" min="3" step="1" onChange={this.handleChange} value={this.state.value}></input> 
     <input type="submit" value="Generate Maze"></input> 
     </form> 
     {this.state.showMazeCom && <Maze size={this.state.value}></Maze>} 
    </div> 
); 
} 

Update:

die unnötige Wieder Zerreißen von Maze Komponente zu vermeiden, verwenden shouldComponentUpdate Lifecycle-Methode, vergleichen, um die neuen und alten Werten Requisiten, wenn sie sind nicht gleich dann nur das erneute Rendern erlauben.

So:

shouldComponentUpdate(nextProps){ 
    if(nextProps.size != this.props.size) 
     return true; 
    return false; 
} 
+0

Wie behalte ich den Irrgarten zwischen rerenders gleich (seinen zufälligen Algorithmus, um es zu generieren)? –

+0

Sie möchten die gesamte Berechnung nur durchführen, wenn sich Requisitenwerte ändern, sonst sollte Maze nicht korrekt ändern ?? –

+0

Ich versuche es nur zu tun, wenn auf die Schaltfläche geklickt wird –

Verwandte Themen