javascript - helmet - reactjs head




Como atualizar o estado dos pais no React? (8)

-Podemos criar ParentComponent e com o método handleInputChange para atualizar o estado ParentComponent. Importe o ChildComponent e passamos dois props do componente pai para o filho, ou seja, a função e a contagem de handleInputChange.

import React from 'react';
import { func, number } from 'prop-types';

const ChildComponent = ({ handleInputChange, count }) => (
  <input onChange={handleInputChange} value={count} name="count" />
);

ChildComponent.propTypes = {
  count: number,
  handleInputChange: func.isRequired,
};

ChildComponent.defaultProps = {
  count: 0,
};

export default ChildComponent;
  • Agora criamos o arquivo ChildComponent e salvamos como ChildComponent.jsx. Este componente é sem estado porque o componente filho não possui um estado. Usamos a biblioteca prop-types para verificar o tipo de adereços.

    class Parent extends React.Component {
      handler = (Value_Passed_From_SubChild) => {
        console.log("Parent got triggered when a grandchild button was clicked");
        console.log("Parent->Child->SubChild");
        console.log(Value_Passed_From_SubChild);
      }
      render() {
        return <Child handler = {this.handler} />
      }
    }
    class Child extends React.Component {
      render() {
        return <SubChild handler = {this.props.handler}/ >
      }
    }
    class SubChild extends React.Component { 
      constructor(props){
       super(props);
       this.state = {
          somethingImp : [1,2,3,4]
       }
      }
      render() {
         return <button onClick = {this.props.handler(this.state.somethingImp)}>Clickme<button/>
      }
    }
    React.render(<Parent />,document.getElementById('app'));
    
     HTML
     ----
     <div id="app"></div>

Minha estrutura é a seguinte:

Component 1  

 - |- Component 2


 - - |- Component 4


 - - -  |- Component 5  

Component 3

O componente 3 deve exibir alguns dados, dependendo do estado do componente 5. Como os objetos são imutáveis, não posso simplesmente salvar seu estado no componente 1 e encaminhá-lo, certo? E sim, eu li sobre redux, mas não quero usá-lo. Espero que seja possível resolvê-lo apenas com reagir. Estou errado?


Encontrei a seguinte solução de trabalho para transmitir o argumento da função onClick de child para o componente pai com param:

classe pai:

class Parent extends React.Component {
constructor(props) {
    super(props)

    // Bind the this context to the handler function
    this.handler = this.handler.bind(this);

    // Set some state
    this.state = {
        messageShown: false
    };
}

// This method will be sent to the child component
handler(param1) {
console.log(param1);
    this.setState({
        messageShown: true
    });
}

// Render the child component and set the action property with the handler as value
render() {
    return <Child action={this.handler} />
}}

classe criança:

class Child extends React.Component {
render() {
    return (
        <div>
            {/* The button will execute the handler function set by the parent component */}
            <Button onClick={this.props.action.bind(this,param1)} />
        </div>
    )
} }

Eu gosto da resposta sobre a passagem de funções, é uma técnica muito útil.

Por outro lado, você também pode conseguir isso usando pub / sub ou usando uma variante, um despachante, como o Flux . A teoria é super simples, o componente 5 envia uma mensagem que o componente 3 está ouvindo. O componente 3 atualiza seu estado que aciona a nova renderização. Isso requer componentes com estado, que, dependendo do seu ponto de vista, podem ou não ser um antipadrão. Sou contra eles pessoalmente e prefiro que outra coisa esteja ouvindo despachos e alterações de estado de cima para baixo (o Redux faz isso, mas adiciona terminologia adicional).

import { Dispatcher } from flux
import { Component } from React

const dispatcher = new Dispatcher()

// Component 3
// Some methods, such as constructor, omitted for brevity
class StatefulParent extends Component {
  state = {
    text: 'foo'
  } 

  componentDidMount() {
    dispatcher.register( dispatch => {
      if ( dispatch.type === 'change' ) {
        this.setState({ text: 'bar' })
      }
    }
  }

  render() {
    return <h1>{ this.state.text }</h1>
  }
}

// Click handler
const onClick = event => {
  dispatcher.dispatch({
    type: 'change'
  })
}

// Component 5 in your example
const StatelessChild = props => {
  return <button onClick={ onClick }>Click me</button> 
}

O pacote do despachante com o Flux é muito simples, ele simplesmente registra retornos de chamada e os invoca quando ocorre qualquer despacho, passando pelo conteúdo do despacho (no exemplo resumido acima, não há payload no despacho, apenas um ID da mensagem). Você pode adaptar isso ao pub / sub tradicional (por exemplo, usando o EventEmitter de eventos ou alguma outra versão) com muita facilidade, se isso fizer mais sentido para você.


Eu usei uma resposta com a melhor classificação nesta página muitas vezes, mas enquanto aprendia o React, encontrei uma maneira melhor de fazer isso, sem vinculação e sem função embutida dentro dos adereços.

Basta olhar aqui:

class Parent extends React.Component {

  constructor() {
    super();
    this.state={
      someVar: value
    }
  }

  handleChange=(someValue)=>{
    this.setState({someVar: someValue})
  }

  render() {
    return <Child handler={this.handleChange} />
  }

}

export const Child = ({handler}) => {
  return <Button onClick={handler} />
}

A chave está em uma função de seta:

handleChange=(someValue)=>{
  this.setState({someVar: someValue})
}

Você pode ler mais here . Espero que isso seja útil para alguém =)


Parece que só podemos passar dados de pai para filho quando a reação promove o fluxo de dados unidirecional, mas para fazer o pai atualizar-se quando algo acontece em seu "componente filho", geralmente usamos o que é chamado de "função de retorno de chamada".

Passamos a função definida no pai para o filho como "adereços" e chamamos essa função do filho, acionando-a no componente pai.

import React, { Component } from 'react';
import ChildComponent from './ChildComponent';

class ParentComponent extends Component {
  constructor(props) {
    super(props);
    this.handleInputChange = this.handleInputChange.bind(this);
    this.state = {
      count: '',
    };
  }

  handleInputChange(e) {
    const { value, name } = e.target;
    this.setState({ [name]: value });
  }

  render() {
    const { count } = this.state;
    return (
      <ChildComponent count={count} handleInputChange={this.handleInputChange} />
    );
  }
}

Neste exemplo, podemos fazer com que os dados passem de SubChild -> Child -> Parent passando a função para seu filho direto.


Quero agradecer a resposta mais votada por me dar a idéia do meu próprio problema, basicamente a variação dele com a função de seta e a passagem de param do componente filho:

 class Parent extends React.Component {
  constructor(props) {
    super(props)
    // without bind, replaced by arrow func below
  }

  handler = (val) => {
    this.setState({
      someVar: val
    })
  }

  render() {
    return <Child handler = {this.handler} />
  }
}

class Child extends React.Component {
  render() {
    return <Button onClick = {() => this.props.handler('the passing value')}/ >
  }
}

Espero que ajude alguém.


Sempre que você precisar se comunicar entre filho e pai em qualquer nível inferior, é melhor usar o contexto . No componente pai, defina o contexto que pode ser chamado pelo filho, como

No componente pai no seu caso, componente 3

static childContextTypes = {
        parentMethod: React.PropTypes.func.isRequired
      };

       getChildContext() {
        return {
          parentMethod: (parameter_from_child) => this.parentMethod(parameter_from_child)
        };
      }

parentMethod(parameter_from_child){
// update the state with parameter_from_child
}

Agora, no componente filho (componente 5 no seu caso), apenas diga a esse componente que deseja usar o contexto de seu pai.

 static contextTypes = {
       parentMethod: React.PropTypes.func.isRequired
     };
render(){
    return(
      <TouchableHighlight
        onPress={() =>this.context.parentMethod(new_state_value)}
         underlayColor='gray' >   

            <Text> update state in parent component </Text>              

      </TouchableHighlight>
)}

você pode encontrar o projeto Demo no repo


então, se você deseja atualizar o componente pai,

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

        handler(val){
            console.log(val) // 1
        }

        render(){
          return (
              <ChildComponent onChange={this.handler} />
           )
       }
   }


class ChildComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
             page:1
        };
    }

    someMethod = (page) => {
        this.setState({ page: page });
        this.props.onChange(page)
    }

    render() {
        return (
       <Button
            onClick={() => this.someMethod()} 
       > Click
        </Button>
      )
   }
}

Aqui onChange é um atributo com o método "manipulador" vinculado à sua instância. passamos o manipulador de método para o componente da classe Child, para receber via onChange a propriedade em seu argumento props.

O atributo onChange será definido em um objeto de props como este:

props ={
onChange : this.handler
}

e passado para o componente filho

Portanto, o componente Filho pode acessar o valor do nome no objeto props como este props.onChange

É feito através do uso de objetos de renderização.

Agora, o componente Filho possui um botão "Clique" com um evento onclick definido para chamar o método manipulador passado a ele via onChnge em seu objeto de argumento props. Portanto, agora this.props.onChange in Child mantém o método de saída na classe Parent Reference e créditos: Bits and Pieces





web-deployment