Классы React: Ссылка на класс как «this» в свойстве функции объекта - PullRequest
0 голосов
/ 05 сентября 2018

Я наконец-то начал использовать реактив и ES6, и все идет хорошо, но я, наконец, озадачен и могу использовать какое-то направление.

Я решил связать this с методом для ссылки на класс, но я пытаюсь пойти немного глубже. Возьмем для примера ... который работает как ожидалось:

class App extends Component {

    state = {
        myFirstState: false,
    };

    handleMyFirstState = () => {
        this.setState( { myFirstState : true } );
    };

    render() {

        return (
            <MyComponent handleMySate={ this.handleMyState } />
        );

    }

}

export default App;

Поскольку количество методов увеличилось, я решил НЕ передавать каждый метод отдельно в качестве реквизита и сначала группировать их в объекте, а просто передавать объект целиком как опору. Как и так ...

class App extends Component {

    state = {
        myFirstState: false,
        mySecondState: false
    };

    handleMyFirstState = () => {
        this.setState( { myFirstState : true } );
    };

    handleMySecondSate = () => {
        this.setState( { mySecondState : true } );
    };



    render() {

        const handleStates = {
            first : this.handleMyFirstState,
            second : this.handleMySecondState
        }

        return (
            <MyComponent handleStates={ handleStates } />
        );

    }

}

export default App;

Теперь я пытаюсь избежать избыточного кода и просто построить методы как один объект с функциями в качестве свойств до начала рендеринга. Примерно так ...

class App extends Component {

    state = {
        myFirstState: false,
        mySecondState: false
    };

    handleStates = {
        // Here is where 'this' does not reference the App class
        // I get results from the console log but setstate doesn't pass correctly
        first : () => { console.log("First Triggered"); this.setState( { myFirstState : true } ); },
        second : () => { console.log("Second Triggered"); this.setState( { mySecondState : true } ); }
    };

    render() {

        return (
            <MyComponent handleStates={this.handleStates} />
        );

    }

}

export default App;

// I trigger the function like this within MyComponent and I get the console log, but `this.setState` breaks.
<Button onClick={ this.props.handleState.first } >Handle First</button>

Я успешно запустил функции из дочернего компонента, <MyComponent/>, используя последний код, но this больше не относится к классу, и я не могу понять, как связать this с handleStates так как это не функция.

Это просто невозможно или есть другой способ справиться с тем, чего я пытаюсь достичь?

Заранее спасибо!

ДОПОЛНИТЕЛЬНЫЙ

Если я переместу handleStates в render(), он будет работать нормально ... как это может быть?

class App extends Component {

    state = {
        myFirstState: false,
        mySecondState: false
    };

    render() {

       const handleStates = {
            first : () => { this.setState( { myFirstState : true } ); },
            second : () => { this.setState( { mySecondState : true } ); }
        };

        return (
            <MyComponent handleStates={this.handleStates} />
        );

    }

}

export default App;

1 Ответ

0 голосов
/ 05 сентября 2018

Во-первых, во втором примере вы передаете this.handleStates в качестве значения для handleStates, но оно не определено. Вы создали handleStates как локальную переменную, и поэтому вы хотите, чтобы ваши реквизиты ссылались на эту локальную переменную:

<MyComponent handleStates={handleStates} />

Для вашего третьего (последнего) примера ваша проблема еще проще: вы определили handleStates как атрибут на this, которому назначен объект, сам с двумя атрибутами, first и second, каждый из которые имеют функцию в качестве значения.

Когда вы в конечном итоге передаете this.handleStates в MyComponent, вы передаете объект, а не функцию. Если вы хотите позвонить одному из first или second из MyComponent, вы можете сделать это следующим образом:

this.props.handleStates.first()

Который имеет желаемый результат обновления состояния в App.

Для чего бы это ни стоило, для этого есть более распространенный шаблон: просто передайте одну функцию обновления как реквизит, названный в соответствии с тем, что он делает:

class Sandwich extends React.Component {
  this.state = {
    bread: "",
    meat: "",
    veggie: "",
  }

  updateSandwich = (component, selection) => {
    this.setState({ [component]: selection })
  }

  render() {
    return(<IngredientSelector updateSandwich={this.updateSandwich} />)
  }
}

class IngredientSelector extends React.Component {
  return(){
    <button value="Rye" onClick={() => this.updateSandwich("bread", "rye")} />
    <button value="Wheat" onClick={() => this.updateSandwich("bread", "wheat")} />
    <button value="Ham" onClick={() => this.updateSandwich("meat", "ham")} />
    <button value="Turkey" onClick={() => this.updateSandwich("meat", "turkey")} />
  }
}
...