2015-12-18 23 views
5

私はカスタムチェックボックスコンポーネントを作成しようとしています(実際には3つの状態ですが、INPUTを使用しているだけではないということ以外は関係ありません)。自分自身のクリックや親から降りてくる値のセットから「チェックネス」を変更します。Reactコンポーネントで状態を管理するには、親からの状態やイベントからの状態を変更することができますか?

現在のところ、クリック後に親コンポーネントに値を送信するために呼び出すハンドラコールバックを使用して、onChangeプロップを実行する自己完結型コンポーネントとして機能しています。状態を使用して、ディスプレイによって参照されるチェックされた状態を保存します。

ディスプレイの値が外から管理されていれば、私は自然に小道具を使用します。初期値を取ってからクリックに反応した自己完結型のチェックボックスコンポーネントだった場合は、私のように状態を使用しますが、問題はクリック可能にしてオンとオフを切り替えることです親はそれをオンとオフにすることができます。

私はリアクションの初心者であり、「リアクションの考え方」だから、私はこの間違いに近づいていると思います。私は、これを行う適切な方法は、クリックするだけで親に対処する表示専用のコンポーネントであり、親からの値変更のための小道具の更新を受け取るという印象を受けるそれは私の心に、コンポーネントをはるかに少ない再利用可能にするだろう。

したがって、内部ソースと親ソースの両方からチェックボックスを変更するにはどうすればよいですか?

関連リンクも歓迎します。

答えて

7

あなたはそれがすべての内部状態を保持するが、唯一の小道具を介して外部からデータを受信し、レンダリングしないことを意味ダムコンポーネント、などのチェックボックスを扱うことそれら。ダムコンポーネントhereの詳細な定義を見ることができます。

一方、チェックボックスがクリックされたときに、このようなイベントは、コンポーネントの親が取り扱う、またはイベントの祖先されますが、これはFacebookのThinking in Reactブログの記事で説明されて反転データフロー、と呼ばれています。

また、特定の状態を保持する必要がありますどのコンポーネントを決定するために、私は非常に便利な次のガイドラインを見つける:

は覚えておいてください:リアクトは、すべてのコンポーネント階層ダウンについての一方向のデータフローです。どのコンポーネントがどの状態を所有すべきかはすぐには分かりません。 これにはそれを把握するために次の手順を実行し、多くの場合、新規参入者が理解するための最も困難な部分、です:

アプリケーション内の状態の各部分について:

  • に基づいて、何かをレンダリングするすべてのコンポーネントを特定しますその状態。
  • 共通の所有者コンポーネント(階層内で状態を必要とするすべてのコンポーネントの上の単一のコンポーネント)を検索します。
  • 共通所有者または上位階層の別のコンポーネントのいずれかが状態を所有する必要があります。
  • 状態を所有するのに意味のあるコンポーネントが見つからない場合は、単に状態を保持するための新しいコンポーネントを作成し、共通所有者コンポーネントの上の階層のどこかに追加します。

は擬似コードスニペット:

const Checkbox = React.createClass({ 
    // Propagate the event to parents 
    onClick(evt) { 
    if (this.props.handleClick) { 
     this.props.handleClick({checked: evt.target.value}); 
    } 
    }, 

    render() { 
    return (
     this.props.checked ? 
     <Input onClick={this.onClick} type="checkbox" label="Checkbox" checked></Input> : 
     <Input onClick={this.onClick} type="checkbox" label="Checkbox"></Input> 
    ); 
    } 
}); 

const Container = React.createClass({ 
    handleClick(evt) { 
    // Change the container's state, which eventually changes the checkbox's view via props. 
    this.setState({checked: evt.checked}); 
    }, 

    render() { 
    return (
     <div><Checkbox checked={this.state.checked} handleClick={this.handleClick}></Checkbox></div> 
    ); 
    } 
}); 
+0

うん、それは私がする必要があるように聞こえる。私は自分の考えを、以前の「バケツ旅団」アイデア(データが個々のコンポーネントによって必要に応じて処理される)からReactが使用する「コントロールの中心点」のアイデアへと移行し始めています。私は、哲学がすべてを網羅していることを認識していませんでした。これは私のハングアップでした。また、記事リンクのおかげで。 – SuperFLEB

3

親からのみ変更します。

class ParentComponent extends React.Component{ 
    handleChildCheck(){ 
    this.setState({ 
    childChecked: !this.state.childChecked 
    }) 
    } 
    render(){ 
    return(
     <ChildComponent checked={this.state.childChecked} handleCheck={this.handleChildCheck.bind(this)} /> 
    ) 
} 
} 

は今、あなただけのthis.handleChildCheck()経由<ParentComponent/>this.props.handleCheck()経由<ChildComponent/>

から<ChildComponent/>内のコントロールは、常に利用できるようになります。この道をthis.props.handleCheck()を呼び出す<ChildComponent/>からチェック状態を制御したい場合。

+0

はオーケー、それを見て、自分でより多くのビットの周りヌードリングした後、私はそれを得ると思います。基本的には、Checkboxコンポーネント(子)は、チェックされた小道具を使用して正しく表示され、親ハンドラー(例ではhandleChildCheck)に相互作用(クリック)イベントを渡すだけですべきです。チェックボックスをどのようにクリックするかのロジックを含む他のすべては、実際にチェックされた小道具を設定しますが、親で処理され、小道具を介して子に落ちる必要があります。 これは正しいと思いますか? – SuperFLEB

+0

はい、正しい。これはリアクションの考え方に沿ったものです! –

-2

querySelectorAllを使用してコンポーネントを検索します。変更を監視するイベントリスナーを追加します。変更時に別のquerySelectorAllを実行して子を見つけ、無効または有効にします。これはあなたのすべてのニーズをカバーするものではないかもしれませんが、正しい方向に着手することができます。これは普通のjavascriptなので、他のライブラリは必要ありません。

// Finds radios with class on-off and disables 'name-on' elements when 
 
// 'name' is off. 
 

 
function initOfOff() { 
 
    var mains = document.querySelectorAll('.on-off'); 
 

 
    for (var i = 0; i < mains.length; i++) { 
 
    var el = mains[i]; 
 
    var name = el.getAttribute('name'); 
 
    el.addEventListener('click', function() { 
 
     var value = this.getAttribute('value'); 
 
     var children = document.querySelectorAll('.' + name + '-on'); 
 
     for (var i = 0; i < children.length; i++) { 
 
     var child = children[i]; 
 
     child.checked = false; 
 
     if (value == "off") { 
 
      child.setAttribute('disabled', 'disabled'); 
 
     } else { 
 
      child.removeAttribute('disabled'); 
 
     } 
 
     } 
 
    }); 
 
    } 
 
} 
 
initOfOff()
<form name='myform'>power 
 
    <input type='radio' value='on' class='on-off' name='power'>ON | 
 
    <input type='radio' value='off' class='on-off' name='power'>Off 
 
    <dir>lights 
 

 
    <input type='radio' value='on' class='power-on' name='lights'>ON | 
 
    <input type='radio' value='off' class='power-on' name='lights'>OFF 
 
    </dir> 
 
</form>

+0

申し訳ありませんが、私はReact特有の解決策を探していると述べていたはずです。 (私は本当にそれほど投稿していないので、分類の詳細については少しばかげている。)タグとタイトルを適宜変更した。しかし、それを掘り下げてくれてありがとう。 – SuperFLEB

関連する問題