2017-06-16 3 views
0

私はチャットプラットフォームを開発して複数のチャットを行い、チャットを切り替えることができます。react/reduxでマルチタブチャットをデザインするには?

var MessageList = React.createClass({ 
    render() { 
     return (
      <div className='messages'> 
      <h2> Conversation: </h2> 
      { 
       this.props.messages.map((message, i) => { 
        return (
         <Message 
          key={i} 
          user={message.user} 
          text={message.text} 
         /> 
       ); 
       }) 
      } 
     </div> 
     ); 
}}) 

ユーザーがチャットタブを切り替えたときに変更されるメッセージリストの例を考えてみましょう。チャットに関してnew messageListを使って同じコンポーネントをレンダリングすることは理にかなっていますが、チャットの切り替えがあるときにこのような100のコンポーネントの変更があると、多くの再描画/レンダリングが行われます( dom内で変更されましたが、まだ変更されています)。

チャットに異なる要素を作成し、アクティブチャットに基づいて非表示にしたいと思います。しかし、反応して1つのdomの下で動作し、返されたものをdomに置き換えます。

React.render(<ChatApp/>, document.getElementById('app')); 

誰でもこのデザインで私を助けることができますか?

ありがとうございます。

+0

これを見てください。 http://www.jeasyui.com/tutorial/layout/tabs2_demo.html# https://github.com/reactabular/reactabular/issues/90 –

答えて

0

var Tabs = React.createClass({ 
 
\t displayName: 'Tabs', 
 
\t propTypes: { 
 
    selected: React.PropTypes.number, 
 
    children: React.PropTypes.oneOfType([ 
 
     React.PropTypes.array, 
 
     React.PropTypes.element 
 
    ]).isRequired 
 
    }, 
 
    getDefaultProps: function() { 
 
    \t return { 
 
    \t selected: 0 
 
    }; 
 
    }, 
 
    getInitialState: function() { 
 
    return { 
 
    \t selected: this.props.selected 
 
    }; 
 
    }, 
 
    shouldComponentUpdate(nextProps, nextState) { 
 
    \t return this.props !== nextProps || this.state !== nextState; 
 
    }, 
 
    handleClick: function (index, event) { 
 
    \t event.preventDefault(); 
 
    this.setState({ 
 
    \t selected: index 
 
    }); 
 
    }, 
 
    _renderTitles: function() { 
 
    \t function labels(child, index) { 
 
    \t var activeClass = (this.state.selected === index ? 'active' : ''); 
 
    \t return (
 
     \t <li key={index}> 
 
     \t <a href="#" 
 
      \t className={activeClass} 
 
      \t onClick={this.handleClick.bind(this, index)}> 
 
      \t {child.props.label} 
 
      </a> 
 
     </li> 
 
    ); 
 
    } 
 
    \t return (
 
    \t <ul className="tabs__labels"> 
 
     \t {this.props.children.map(labels.bind(this))} 
 
     </ul> 
 
    ); 
 
    }, 
 
    _renderContent: function() { 
 
    \t return (
 
    \t <div className="tabs__content"> 
 
\t  \t {this.props.children[this.state.selected]} 
 
     </div> 
 
    ); 
 
    }, 
 
\t render: function() { 
 
    \t return (
 
    \t <div className="tabs"> 
 
     {this._renderTitles()} 
 
     \t {this._renderContent()} 
 
     </div> 
 
    ); 
 
    } 
 
}); 
 

 
var Pane = React.createClass({ 
 
\t displayName: 'Pane', 
 
    propTypes: { 
 
    label: React.PropTypes.string.isRequired, 
 
    children: React.PropTypes.element.isRequired 
 
    }, 
 
\t render: function() { 
 
    \t return (
 
    \t <div> 
 
     \t {this.props.children} 
 
     </div> 
 
    ); 
 
    } 
 
}); 
 

 
var App = React.createClass({ 
 
\t render: function() { 
 
    \t return (
 
    \t <div> 
 
     <Tabs selected={0}> 
 
      <Pane label="Tab 1"> 
 
      <div>This is my tab 1 contents!</div> 
 
      </Pane> 
 
      <Pane label="Tab 2"> 
 
      <div>This is my tab 2 contents!</div> 
 
      </Pane> 
 
      <Pane label="Tab 3"> 
 
      <div>This is my tab 3 contents!</div> 
 
      </Pane> 
 
     </Tabs> 
 
     </div> 
 
    ); 
 
    } 
 
}); 
 
    
 
ReactDOM.render(<App />, document.querySelector('.container'));
* { 
 
    box-sizing: border-box; 
 
    -webkit-box-sizing: border-box; 
 
    -moz-box-sizing: border-box; 
 
} 
 
body { 
 
    font: 300 14px/1.4 'Helvetica Neue', Helvetica, Arial, sans-serif; 
 
    background: #eee; 
 
    margin: 0; 
 
    padding: 0; 
 
} 
 
.tabs { 
 
    margin: 25px; 
 
    background: #fff; 
 
    border: 1px solid #e5e5e5; 
 
    border-radius: 3px; 
 
} 
 
.tabs__labels { 
 
    margin: 0; 
 
    padding: 0; 
 
} 
 
.tabs__labels li { 
 
    display: inline-block; 
 
} 
 
.tabs__labels li a { 
 
    padding: 8px 12px; 
 
    display: block; 
 
    color: #444; 
 
    text-decoration: none; 
 
    border-bottom: 2px solid #f5f5f5; 
 
} 
 
.tabs__labels li a.active { 
 
    border-bottom-color: #337ab7; 
 
} 
 
.tabs__content { 
 
    padding: 25px; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 

 
<div class="container"></div>

+0

詳細な説明をいただきありがとうございます。 @Praveen しかし、この場合、多くのタブがそこにあるのが分かりますが、私の場合は動的です。私はを動的に作成し、他のタブに触れたりレンダリングしたりすることなく、他のドムと同じdomの下にそれを接続します!これをどのように反応させることができますか? – iamshravan

+0

あなたは簡単にこのような何か実行して、それを動的にすることができます: のconstペイン=({} anArrayOfIndividualPaneObjects)=>(

{anArrayOfIndividualPaneObjects.map(pane => ( \t
pane.contents
))}
を)。 Appコンポーネントからペインの配列を渡します。また、Appコンポーネントのこの配列に新しいオブジェクトを追加するメソッドを持つことで、新しいタブを動的に追加することもできます –

0

あなたはReduxのを言っているので、それはあまりにも大きい/複雑になるだろうので、私は、任意のコードを提供するために、いくつかの洞察が、怠惰を与えることをしようとするでしょう。

必要に応じて、ネストされたJSON形式で扱うときにnormalizrを使用することができます。これは、還元が不変でネストされているため不変にすることが難しくなります。

減速:

chats { userid:"", message:"", time:"" }, 
users { userid:"", name:"" }, 
app { selectedUserId:"" } 

今、ある表示/レンダリングされるタブの数は、ユーザーの数に等しいです。選択したタブはapp.selectedUserIdに基づいています。パネルでレンダリングされるメッセージはチャットで、useridapp.selectedUserIdとなります。いくつかのスニペット:

var lo = require('lodash'); 
var selectedChats = lo.filter(this.props.chats, k => k.userid == app.selectedUserId); 

var messagesDom = selectedChats.map(k => <MessageLine chat={k}); 
var chatTabsDom = this.props.users.map(k => <ChatTab userid={k.userid} className={ k.userid == app.selectedUserId ? "active" : "" }>); 

return <div> 
    <Tabs>{chatTabsDom}</Tabs> 
    <Messages>{messagesDom}</Messages> 
</div>; 
関連する問題