2016-05-28 3 views
0

私はReactの初心者ですが、Reactを使ってアプリケーションを作成しようとしていましたが、何時間も試してみた結果、私が削除したい要素がなぜあるのか理解できませんでしたonClick aren '削除されました。反応がある要素を削除する方法は? (基本的な質問)

これには2つの似た記事があり、それぞれの要素に独立したキーを使用する必要があると言われています。私はそれをやろうとしました。私は別の変数を作成し、使用するたびにそれをインクリメントしました。 リストの一番上の要素を削除するだけです。

どのように動作する - 1)私はいくつかの名前channelsに格納された配列を持っている、と私はその名前を持つデータを取得し、別の配列renderAllにそのデータを保存します。

2)その後、どのようにレンダリングするかをフィルタリングしてから、関数renderCards()でレンダリングします。また、ボタンをクリックすると、channelアレイからチャネルが削除され、renderAllアレイのそれぞれのデータが削除されます。

3)チャンネルを追加できる入力フィールドもあります。

- 削除ボタンは、クリックされた要素の代わりに最上位の要素を削除します。

I have the app running without the delete functionality

var App = React.createClass({ 
    getInitialState() { 
     return { 
      status: 2 
     } 
    }, 
    changeStatus(i) { 
     this.setState({ 
      status: i 
     }); 
    }, 
    render() { 
     return (
      <div> 
       <header><h1>Twitch Streamers</h1></header> 
       <Tabs status = {this.changeStatus} /> 
       <Cards status = {this.state.status} /> 
      </div> 
     ); 
    } 
}); 


const Cards = React.createClass({ 
    getInitialState() { 
     return { 
      renderAll: [], 
      check: this.props.status, 
      channels: ["freecodecamp", "storbeck", "habathcx","meteos","RobotCaleb","noobs2ninjas","brunofin","comster404","cretetion","sheevergaming","TR7K","OgamingSC2","ESL_SC2"] 
     }; 
    }, //AJAX REQUEST FUNCTION 
    getData(last) { 
     if(last === undefined) { 
      for(let i =0; i<this.state.channels.length;i++) { 
       let channel = this.state.channels[i]; 
       $.getJSON("https://api.twitch.tv/kraken/streams/" + channel, (data) => { 
        $.getJSON("https://api.twitch.tv/kraken/channels/" + channel, (logo) => { 
         if(data.hasOwnProperty(status) === false) { 
          if(data.stream === null) { 
           this.setState({ 
            renderAll: this.state.renderAll.concat([{channel: channel, url: `https://www.twitch.tv/${channel}`, status: 'offline', logo: logo.logo}]) 
           }); 
          } else { 
           this.setState({ 
            renderAll: this.state.renderAll.concat([{channel: data.stream.channel.name, url: `https://www.twitch.tv/${channel}`, current: data.stream.channel.game + ' - ' + data.stream.channel.status, status: 'online', logo: logo.logo}]) 
           }); 
          } 
         } 
        }); 
       }) 
       .fail((jqxhr) => { 
        this.setState({ 
         renderAll: this.state.renderAll.concat([{channel: channel, status: 'closed'}]) 
        }); 
       }); 
      } 
     } else { 
      let channel = this.state.channels[this.state.channels.length - 1]; 
      $.getJSON("https://api.twitch.tv/kraken/streams/" + channel, (data) => { 
       $.getJSON("https://api.twitch.tv/kraken/channels/" + channel, (logo) => { 
        if(data.hasOwnProperty(status) === false) { 
         if(data.stream === null) { 
          this.setState({ 
           renderAll: this.state.renderAll.concat([{channel: channel, url: `https://www.twitch.tv/${channel}`, status: 'offline', logo: logo.logo}]) 
          }); 
         } else { 
          this.setState({ 
           renderAll: this.state.renderAll.concat([{channel: data.stream.channel.name, url: `https://www.twitch.tv/${channel}`, current: data.stream.channel.game + ' - ' + data.stream.channel.status, status: 'online', logo: logo.logo}]) 
          }); 
         } 
        } 
       }); 
      }) 
      .fail((jqxhr) => { 
       this.setState({ 
        renderAll: this.state.renderAll.concat([{channel: channel, status: 'closed'}]) 
       }); 
      }); 
     } 
    }, 
    componentWillMount() { 
     this.getData(); 
    }, 
    componentWillReceiveProps(prop) { 
     this.setState({ 
      check: prop 
     }); 
    }, //DELETE FUNCTION THAT DOESN'T WORK 
    delete(index) { 
     let newArr = this.state.channels.slice(); 
     let newArrSecond = this.state.renderAll.slice(); 

     newArr.splice(index, 1); 
     newArrSecond.splice(index, 1); 

     this.setState({ 
      channels: newArr, 
      renderAll: newArrSecond 
     }); 
    }, //RENDER CARDS FUNCTION 
    renderCards(i) { 
     if(i === 0 || i.status === 0) { 
      let cards = this.state.renderAll.map((item, i) => { 
       if(item.status === 'online') { 
        return <div className="online cards" key={i}><img src={item.logo} width="30px" height="30px" /><a target="_blank" href={item.url}><h3>{item.channel}</h3></a><button className="cross" onClick={this.delete}>✕</button><p>{item.current}</p></div> 
       } 
      }); 
      return (
       cards 
      ) 
     } else if(i === 1 || i.status === 1) { 
      let cards = this.state.renderAll.map((item, i) => { 
       if(item.status === 'offline') { 
        return <div className="offline cards" key={i}><img src={item.logo} width="30px" height="30px"/><a target="_blank" href={item.url}><h3>{item.channel}</h3></a><button className="cross" onClick={this.delete}>✕</button><p>Channel is offline</p></div> 
       } 
      }); 
      return (
       cards 
      ) 
     } else if(i === 2 || i.status === 2) { 
      let cards = this.state.renderAll.map((item, i) => { 
       if(item.status === 'offline') { 
        return <div className="offline cards" key={i}><img src={item.logo} width="30px" height="30px" /><a target="_blank" href={item.url}><h3>{item.channel}</h3></a><button className="cross" onClick={this.delete}>✕</button><p>Channel is offline</p></div> 
       } else if(item.status === 'online') { 
        return <div className="online cards" key={i}><img src={item.logo} width="30px" height="30px" /><a target="_blank" href={item.url}><h3>{item.channel}</h3></a><button className="cross" onClick={this.delete}>✕</button><p>{item.current}</p></div> 
       } else { 
        return <div className="closed cards" key={i}><h3>{item.channel}</h3><p>Account Closed</p></div> 
       } 
      }); 
      return (
       cards 
      ) 
     } 
    }, 
    newChannel(i) { 
     if(i.keyCode === 13) { 
      this.setState({channels: this.state.channels.concat([i.target.value])}, function() { 
       this.getData(1); 
      }); 
     } 
    }, 
    leave(i) { 
     i.target.value = ''; 
    }, 
    render() { 
     return (
      <div id="cards-inside"> 
       <input type='text' placeholder="+ Channel" onKeyDown={this.newChannel} onBlur={this.leave}/> 
       <ReactCSSTransitionGroup transitionName="example" transitionEnterTimeout={500} transitionLeaveTimeout={300}> 
        {this.renderCards(this.state.check)} 
       </ReactCSSTransitionGroup> 
      </div> 
     ) 
    } 
}); 

ReactDOM.render(<App />, document.getElementById("container-second")); 

答えて

1

あなたがdeleteを呼び出すときにそれを渡すことはありませんので、ごindexは、常に0です。

したがって、常に最上位の要素が削除されます。

onClick={this.delete.bind(this, i)} 

をクリックしたか、カードのインデックスを渡すために

OnClick={() => {this.delete(i)} } 

を試してみてください。

あなたがXをレンダリングJSXビットの内部では、あなたが行う必要があります。

+0

、:

の作業例「警告:バインド():コンポーネントのメソッドが唯一のコンポーネントのインスタンスにバインドすることができる反応させ、カードを参照してください。」 – Lavios

+0

I問題の原因がインデックスを渡す必要があることを確認してください。私は答えを更新しました。 – wintvelt

+0

ありがとう! 2番目の声明 – Lavios

0

Reactでは、jQueryのようにノードを「削除」する必要はありません。

のは、あなたの初期状態での名前のリストを持っているとしましょう:あなたのrender()方法で

class MyComponent extends React.Component { 
    state = { 
    names: ['Foo', 'Bar', 'Git', 'Get'] 
    }; 
    [...] 
} 

、あなたがul内でそれらをレンダリングされます。

render() { 
    const names = this.state.names.map(name => { 
    return <li key={name} onClick={this.remove.bind(this, name)}>{name}</li>; 
    }); 
    return <ul>{names}</ul>; 
} 

必要になりますあなたのremove()方法で持っている:

remove(name) { 
    this.setState({ 
    names: this.state.names.filter(cur => cur !== name) 
    }); 
} 

今、ev削除する名前をクリックすると、名前リストから名前が削除され、コンポーネントが再度レンダリングされ、削除された名前がDOMから削除されます。それは動作しません、それはまた、余分なエラーを与える
http://codepen.io/FezVrasta/pen/MeWpzm?editors=0010