Estou essencialmente tentando fazer as guias reagirem, mas com alguns problemas.
Aqui está o arquivo page.jsx
<RadioGroup>
<Button title="A" />
<Button title="B" />
</RadioGroup>
Quando você clica no botão A, as necessidades de componentes RadioGroup para de-selecionar o botão B .
"Selecionado" significa apenas um className de um estado ou propriedade
Aqui está RadioGroup.jsx
:
module.exports = React.createClass({
onChange: function( e ) {
// How to modify children properties here???
},
render: function() {
return (<div onChange={this.onChange}>
{this.props.children}
</div>);
}
});
A fonte de Button.jsx
realmente não importa, ele tem um botão de opção HTML regular que aciona o onChange
evento DOM nativo
O fluxo esperado é:
- Clique no botão "A"
- O botão "A" aciona onChange, evento DOM nativo, que borbulha para RadioGroup
- O ouvinte RadioGroup onChange é chamado
- RadioGroup precisa de-selecione o botão B . Esta é a minha pergunta.
Aqui está o principal problema que estou encontrando: não consigo <Button>
entrarRadioGroup
, porque a estrutura disso é que os filhos são arbitrários . Ou seja, a marcação pode ser
<RadioGroup>
<Button title="A" />
<Button title="B" />
</RadioGroup>
ou
<RadioGroup>
<OtherThing title="A" />
<OtherThing title="B" />
</RadioGroup>
Tentei algumas coisas.
Tentativa:RadioGroup
manipulador onChange de In :
React.Children.forEach( this.props.children, function( child ) {
// Set the selected state of each child to be if the underlying <input>
// value matches the child's value
child.setState({ selected: child.props.value === e.target.value });
});
Problema:
Invalid access to component property "setState" on exports at the top
level. See react-warning-descriptors . Use a static method
instead: <exports />.type.setState(...)
Tentativa:RadioGroup
manipulador onChange de In :
React.Children.forEach( this.props.children, function( child ) {
child.props.selected = child.props.value === e.target.value;
});
Problema: nada acontece, até eu dou Button
um componentWillReceiveProps
método para a classe
Tentativa: tentei passar algum estado específico do pai para os filhos, então posso apenas atualizar o estado dos pais e fazer com que os filhos respondam automaticamente. Na função render do RadioGroup:
React.Children.forEach( this.props.children, function( item ) {
this.transferPropsTo( item );
}, this);
Problema:
Failed to make request: Error: Invariant Violation: exports: You can't call
transferPropsTo() on a component that you don't own, exports. This usually
means you are calling transferPropsTo() on a component passed in as props
or children.
Solução ruim nº 1 : use o método react-addons.js cloneWithProps para clonar os filhos no tempo de renderização RadioGroup
para poder passar propriedades para eles
Solução ruim nº 2 : implemente uma abstração em torno de HTML / JSX para que eu possa passar as propriedades dinamicamente (me mate):
<RadioGroup items=[
{ type: Button, title: 'A' },
{ type: Button, title: 'B' }
]; />
Em seguida, RadioGroup
crie esses botões dinamicamente.
Esta pergunta não me ajuda porque preciso renderizar meus filhos sem saber o que são
RadioGroup
saber que precisam reagir a um evento de seus filhos arbitrários? Ele necessariamente tem que saber algo sobre seus filhos.React.addons.cloneWithProps
e passe os novos adereços que gostaria que ele tivesse.props
são imutáveis, então você está criando um novo hash, mesclando-o com os adereços atuais e passando o novo hashprops
para uma nova instância do componente filho.Respostas:
Não sei por que você diz que usar
cloneWithProps
é uma solução ruim, mas aqui está um exemplo prático de como usá-lo.Aqui está um jsFiddle mostrando em ação.
EDIT : aqui está um exemplo mais completo com conteúdo de guia dinâmico: jsFiddle
fonte
this
. Existe alguma vantagem real, além de ter usado React?Os botões devem ser sem estado. Em vez de atualizar as propriedades de um botão explicitamente, apenas atualize o próprio estado do Grupo e renderize novamente. O método de renderização do Grupo deve então observar seu estado ao renderizar os botões e passar "ativo" (ou algo assim) apenas para o botão ativo.
fonte
Talvez a minha seja uma solução estranha, mas por que não usar o padrão do observador?
talvez você precise de outra coisa, mas eu achei isso muito poderoso,
Eu realmente prefiro usar um modelo externo que forneça métodos de registro de observador para várias tarefas
fonte
Button.jsx
?onChange()
eonChange(e)
Crie um objeto que atue como um intermediário entre o pai e o filho. Este objeto contém referências de função no pai e no filho. O objeto é então passado como um suporte do pai para o filho. Exemplo de código aqui:
https://stackoverflow.com/a/61674406/753632
fonte