2016-12-16 10 views
0

OK、これはノブの質問で、おそらく私の鼻の下の答えですが、これを行う方法を理解できないようです。基本的には、ReactでTo-doリストを作成していて、ユーザーが項目を完成したものとしてマークする方法が必要です。React JSのボタンをクリックすると、LI要素が非アクティブ状態に設定されます

私は親コンテナの状態を介して設定しようとしましたが、その状態を要素propsでアクセスしようとしましたが、動作しません。

ここまでは私のコードです。 getInitialState関数、onCompleted、ListContainerの戻り値関数、およびItemを参照してください。

var ListContainer = React.createClass({ 
    getInitialState: function() { 
    return { 
     numChildren: 0, 
     list: [], 
     disabled: false 
    }; 
    }, 
    onAddChild: function() { 
    var inputValue = document.getElementById('itemAdder').value; 
    var ul = document.getElementById('list'); 

    var newList = this.state.list; 
    if(inputValue !== '') { 
     newList.push(inputValue); 
     ul.style.display = 'block'; 
    } 
    this.setState({ 
     numChildren: this.state.numChildren + 1, 
     list: newList 
    }); 
    }, 
    onDeleteChild: function(index) { 
    this.state.list.splice(index, 1); 
    this.setState({ 
     list: this.state.list 
    }); 
    }, 
    onCompleted: function() { 
    this.setState({ 
     disabled: true 
    }); 
    }, 
    render: function() { 
    var children = []; 
    for (var i = 0; i < this.state.list.length; i++) { 
     children.push(<Item key={'item_' + i} number={i} onDeleteChild={this.onDeleteChild} completed={this.state.onCompleted} content={this.state.list[i]}/>); 
    }; 
    return (
     <List addChild={this.onAddChild}> 
     {children} 
     </List> 
    ); 
    } 
}); 

var List = React.createClass({ 
    render: function() { 
    return (
     <div id="listContainer"> 
     <h1 className="no-margins even-padding page-header ">To do list</h1> 
     <div className="even-padding form-inline"> 
      <input type="text" name="itemAdder" id="itemAdder" className="form-control" placeholder="Enter things that need doing..." /> 
      <button type="button" className="btn btn-primary" onClick={this.props.addChild}>Add item</button> 
      <ul id="list" className="no-margins list"> 
      {this.props.children} 
      </ul> 
     </div> 
     </div> 
    ); 
    } 
}); 

var Item = React.createClass({ 
    complete: function() { 
    this.props.completed; 
    }, 
    delete: function() { 
    this.props.onDeleteChild(this.props.number); 
    }, 
    render: function() { 
    return (
     <li className="clearfix"> 
     {this.props.content} 
     <div className="pull-right"> 
      <button onClick={this.complete} id="completed" className="btn btn-success btn-xs">&#x2714;</button> 
      <button id="remove" onClick={this.delete} className="btn btn-danger btn-xs">&#x2718;</button> 
     </div> 
     </li> 
    ); 
    } 
}); 

var App = React.createClass({ 
    render: function() { 
    return (
     <div id="main" className="page-wrap"> 
     <ListContainer /> 
     </div> 
    ); 
    } 
}); 

ReactDOM.render(
    <App/>, 
    document.getElementById('app') 
); 

ご協力いただきありがとうございます。

+0

を作ります各オブジェクトに値とその状態が含まれているオブジェクトを持つ配列。例: 'list:[{value:" foo "、state:0}、{value:" bar "、state:1}]' – Chris

+0

ですが、_value_とは何ですか? –

答えて

1

まず、forループ内の子リストが正しくありません。完成した小道具は、次のように渡す必要があります。

for (var i = 0; i < this.state.list.length; i++) { 
    children.push(<Item key={'item_' + i} number={i} onDeleteChild={this.onDeleteChild} completed={this.onCompleted} content={this.state.list[i]}/>); 
}; 

また、構造化された状態の構造が正しくありません。リスト内のすべての項目は、独自のプロパティを無効にする必要があります。そうしないと、すべてのアイテムが無効になるか、すべてのアイテムが有効になります。

for (var i = 0; i < this.state.list.length; i++) { 
    children.push(<Item key={'item_' + i} number={i} onDeleteChild={this.onDeleteChild} completed={this.onCompleted} content={this.state.list[i].value}/>); 
}; 

:今、このようなあなたの子供のリストを変更、それを修正getInitialStateのあなたのreturn文から無効な属性を削除し、あなたのonAddChild方法

onAddChild: function() { 
var inputValue = document.getElementById('itemAdder').value; 
var ul = document.getElementById('list'); 

var newList = this.state.list; 
if(inputValue !== '') { 
    newList.push({value: inputValue, disabled: false}); 
    ul.style.display = 'block'; 
} 
this.setState({ 
    numChildren: this.state.numChildren + 1, 
    list: newList 
}); 

}

を変更するには

今すぐあなたのonCompletedメソッドは、更新する必要がある項目のインデックスを渡さなければなりません

onCompleted: function(itemIndex) { 
    var newList = this.state.list.slice(); 
    newList[itemIndex].disabled = true; 
    this.setState({ 
     list: newList 
    }); 
} 

最後に、Itemコンポーネントのrenderメソッドを更新する必要があります。最初のボタンのonclickのは、このようなリストコンポーネント内部完全方法変更すなわちトリガーされたときにだけ、リストの項目のインデックスを渡します。その代わり、単に値を持つ配列であることあなたのリストの

complete: function() { 
    this.props.completed(this.props.number) // Passing the index of the item as an argument 
} 
+0

あなたの答えをありがとう。しかし、この行では小さな問題が発生します: 'newList.push({value:inputValue、disabled:false});' _value_から '予期しない型キャスト'エラーが発生します。私は何をする必要がありますか?乾杯! –

+0

エラーが表示されませんhttps://jsfiddle.net/swapnil95/rdfdn5d4/2/ コンソールを開き、更新された状態を確認してください – Swapnil

+0

OKですが、要素を無効にしていませんか? –

関連する問題