2017-02-21 16 views
6

W React Próbuję zrobić przycisk, aby zwiększyć wartość przechowywaną w stanie. Jednak używając poniższego kodu funkcja moja wartość jest niezdefiniowana lub NaN podczas używania handleClick.Zwiększanie wartości stanu o jeden przy użyciu React

class QuestionList extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = {value: 0}; 

    // This binding is necessary to make `this` work in the callback 
    this.handleClick = this.handleClick.bind(this); 
    } 

    handleClick = (prevState) => { 
    this.setState({value: prevState.value + 1}); 
    console.log(this.state.value) 
    } 

Czy możesz mi powiedzieć, dlaczego tak się dzieje? Powinno być poprawne, zgodnie z dokumentacją tutaj: https://facebook.github.io/react/docs/state-and-lifecycle.html

Odpowiedz

3

Ustaw stan jest asynchronizowany, więc nie zobaczysz aktualizacji wartości, gdy nastąpi console.log. Powinieneś wydrukować wartość stanu w interfejsie użytkownika, abyś mógł zobaczyć, co się dzieje. Aby naprawić log konsoli, spróbuj tego.

class QuestionList extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = {value: 0}; 
    } 

    handleClick = (prevState) => { 
    this.setState({value: prevState.value + 1},() => { 
     console.log(this.state.value) 
    }); 
    } 

UWAGA: jeśli zdefiniować lambda inline (funkcja strzałka) dla reagują klasa this jest związany prawidłowo więc nie musisz powiązać go w konstruktorze.

także można zmienić sposób przekazać poprzednią liczbę, jeśli jej tylko przyrost stanu jak ten

handleClick =() => { 
    this.setState({value: this.state.value + 1},() => { 
     console.log(this.state.value) 
    }); 
} 
+0

Thanks I potrzebne, aby nie używać prevState . – dwigt

+0

@ Zauważ, że zauważyłeś, że zmieniłem twój dziennik konsoli, aby być w callbacku dla twojej funkcji setstate. ponieważ logi wbudowanej konsoli zostanie wykonane, gdy wątek trafi go po wywołaniu funkcji setstate, a nie zakończeniu aktualizacji stanu :) –

1

Spróbuj tego

class QuestionList extends React.component { 

    constructor(props){ 
     super(props) 
     this.state = { 
      value : 0 
     } 
    } 

    handleClick(){ 
     this.setState({ 
      value : this.state.value + 1 
     }) 
    } 

    render(){ 
     return(<button type="button" onClick={this.handleClick.bind(this)}> {this.state.value} </button>) 
    } 
} 

Należy pamiętać, że po ustawieniu stan, to wyzwala funkcja renderowania, która będzie odzwierciedlać bieżący stan. Wypróbuj w przeglądarce!

6

Ponieważ funkcja handleClick jest używana niepoprawnie. Tutaj:

handleClick = (prevState) => { .... } 

prevState będzie obiektem zdarzenia przekazywane do funkcji handleClick, trzeba użyć prevState z setstate, tak:

handleClick =() => { 
    this.setState(prevState => { 
     return {count: prevState.count + 1} 
    }) 
} 

Inną kwestią jest, setstate jest asynchroniczny tak console.log(this.state.value) nie drukuje zaktualizowana wartość stanu, musisz użyć funkcji wywołania zwrotnego z setState.

Sprawdź więcej szczegółów na temat async behaviour of setState i jak sprawdzić zaktualizowaną wartość.

Sprawdź roztwór roboczy:

class App extends React.Component { 
 
    
 
    constructor(props){ 
 
     super(props); 
 
     this.state={ count: 1} 
 
    } 
 
    
 
    onclick(type){ 
 
     this.setState(prevState => { 
 
     return {count: type == 'add' ? prevState.count + 1: prevState.count - 1} 
 
     }); 
 
    } 
 

 
    render() { 
 
    return (
 
     <div> 
 
     Count: {this.state.count} 
 
     <br/> 
 
     <div style={{marginTop: '100px'}}/> 
 
     <input type='button' onClick={this.onclick.bind(this, 'add')} value='Inc'/> 
 
     <input type='button' onClick={this.onclick.bind(this, 'sub')} value='Dec'/> 
 
     </div> 
 
    ) 
 
    } 
 
} 
 

 
ReactDOM.render(
 
    <App />, 
 
    document.getElementById('container') 
 
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 

 
<div id='container'></div>

1
class SkuVariantList extends React.Component { 
    constructor(props) { 
     super(props) 
     this.state = { 
     clicks: 0 
     }; 
     this.clickHandler = this.clickHandler.bind(this) 
    } 

    componentDidMount() { 
     this.refs.myComponentDiv.addEventListener('click', this.clickHandler); 
    } 

    componentWillUnmount() { 
     //this.refs.myComponentDiv.removeEventListener('click', this.clickHandler); 
    } 

    clickHandler() { 
     var clk = this.state.clicks 
     this.setState({ 
     clicks: clk + 1 
     }); 
    } 

    render() { 
     let children = this.props.children; 

     return (
     <div className="my-component" ref="myComponentDiv"> 
      <h2>My Component ({this.state.clicks} clicks})</h2> 
      <h3>{this.props.headerText}</h3> 
      {children} 
     </div> 
    ); 
    } 
    } 
0

Witam, spróbuj tych kodów, aby zwiększyć swoją wartość

class Counter extends React.Component{ 
constructor(props){ 
    super(props); 
    this.addOne = this.addOne.bind(this); 
     this.state = { 
     count : 0 
     } 
    } 

addOne() {        // addOne as HandleClick 
    this.setState((preState) => { 
    return { 
     count : preState.count + 1 
     }; 
    }); 
} 

render() { 
    return (
     <div> 
     <h1>Count : {this.state.count}</h1> 
     <button onClick={this.addOne}>+1</button> 
     </div> 
    ); 
    } 
} 

ReactDOM.render(<Counter />, document.getElementById('YOUR-ID')); 
Powiązane problemy