2016-06-29 11 views
0

私はリアクション(下)にレイアウトコンポーネントを持っています。 this.props.children(または今はchildrenWithProps)を介してこのコンポーネントに注入されるコンポーネントの2つに、ユーザーがデータの範囲を選択できるようにするために作成した日付範囲コンポーネントがあります。 1つはプレーヤーダッシュボードで、もう1つはチームダッシュボードです(デフォルトのビューと2番目のコードブロックに表示されています)。ユーザーがチームダッシュボードにいてプレイヤーを検索してそのプレーヤーのダッシュボードに移動すると、選択した日付範囲(this.state.startDateとthis.state.EndDateとして保存されています)がプレーヤーのダッシュボードに持ち越され、その逆も同様です。私はこれがreduxの良いユースケースだと思っていますが、これまでのところ、私は小道具を渡すだけで成功しましたが、日付範囲のためのreduxの実装は難しいようです。どんな助けでも大歓迎です。また、私は反応することが新しく、かなりの量の再フォーマットを行う必要があることを知っています。ここで 親/子でないコンポーネント間で日付変更を処理するReact.js

import React, { PropTypes, Component } from 'react'; 
import '../../styles/core.scss'; 
import TopNav from 'components/top-nav'; 
import LeftNav from 'components/left-nav'; 

export default class CoreLayout extends Component { 
    static propTypes = { 
    children: PropTypes.element 
}; 

constructor(props, context) { 
    super(props, context); 
    this.state = { 
     team: null, 
     teamPositions: [] 
    }; 
} 

activeTeam(team){ 
    console.log(team); 
    this.setState({ 
     team: team 
    },() => { 
     return this.state; 
    }); 
} 

componentWillMount() { 
} 

getTeamPositions(positions){ 
    this.setState({ 
     teamPositions: positions 
    },() => { 
     return this.state; 
    }); 
} 

render() { 
    var childrenWithProps = React.Children.map(this.props.children, (child) => React.cloneElement(child, { team: this.state.team, teamPositions: this.state.teamPositions })); 
    return (
     <div className='page-container'> 
      <TopNav 
      onTeamChange={team => this.activeTeam(team)} 
      sendTeamPositions={positions => this.getTeamPositions(positions)} 
      /> 
      <LeftNav /> 
      {(this.state.team !== null) ? 
     <div className='view-container'> 
      { childrenWithProps } 
     </div> 
     : null } 
     </div> 
    ); 
    } 
} 

はReduxのは、親に日付範囲の状態を移動させることでなくて、私は最善の策を言うと思いますあなたのコードを見てみるとチームのダッシュボード

import React, { PropTypes, Component } from 'react'; 
import { getDataRange, getTeams, getFile, getAllHitsData, getPlayers} from 'api/index.js'; 
import moment from 'moment'; 
import {Table, Thead, Th, Tr, Td} from 'components/Reactable'; 
import Autosuggest from 'react-autosuggest'; 
import { Link } from 'react-router'; 
import ScatterPlot from 'components/scatterplot'; 
import DashboardStats from 'components/dashboard-stats'; 
import DateRangeComponent from 'components/date-range'; 
import AdminSquare from 'components/admin-square'; 

let allHitDatas = []; 
let hitDatas = []; 
let teams = []; 
let newFile = ''; 
let players = []; 

export default class Dashboard extends Component { 
    static propTypes = { 
    team: PropTypes.object.isRequired 
    // teamPositions: PropTypes.array.isRequired 
}; 
constructor(props, context) { 
    super(props, context); 
    this.state = { 
     showRangePicker: false, 
     hitDatas: [], 
     teams: [], 
     start: '', 
     end: '', 
     team: this.props.team, 
     selectedTeamID: null, 
     selectedTeamName: "", 
     newFileConfirmation: false, 
     players: [], 
     allHitDatas: [], 
     suggestions: this.getSuggestions(''), 
     startDate: moment().format('YYYY-MM-DD'), 
     endDate: moment().format('YYYY-MM-DD'), 
     selected: '', 
     showDatePickerControls: false, 
     showScatterPlot: true 
    }; 
    this.onChange = this.onChange.bind(this); 
    this.onSuggestionsUpdateRequested = this.onSuggestionsUpdateRequested.bind(this); 
} 

onChange(event, { newValue }) { 
    this.setState({ 
     value: newValue 
    }); 
} 

onSuggestionsUpdateRequested({ value }) { 
    this.setState({ 
     suggestions: this.getSuggestions(value) 
    }); 
} 

    formatDate(date) { 
    return moment(date).format('YYYY-MM-DD'); 
    } 

    formatDisplayDate(date) { 
    return moment(date).format('MMMM DD, YYYY'); 
    } 

    componentWillReceiveProps() { 
     this.setState({ 
     team: this.props.team, 
     selectedTeamID: this.props.team.id 
    },() => { 
     this.dataChangeHelper(); 
    }); 
     console.log(this.props); 
    } 

    componentWillMount() { 
    console.log(this.props); 
    let defaultStartDate = "03/01/15"; 
    let defaultEndDate = "05/18/16"; 
    const config = { 
     start: this.state.startDate || defaultStartDate, 
     end: this.state.endDate || defaultEndDate, 
     team: this.props.team.id 
    }; 

    getAllHitsData(config) 
    .then((response) => { 
     allHitDatas = response.data; 
     this.setState({ 
     allHitDatas: allHitDatas 
     },() => { 
      return this.state; 
     }); 
    }); 

    getDataRange(config) 
     .then((response) => { 
      hitDatas = response.data; 
      this.setState({ 
       hitDatas: hitDatas, 
       start: config.start, 
       end: config.end 
      }); 
     }); 
    getTeams().then((response) => { 
     teams = response.data; 
     this.setState({teams: teams}); 
    }); 

    getPlayers().then((response) => { 
     players = response.data; 
     this.setState({ 
      players: players 
     },() => { 
       return this.state; 
     }); 
    }); 
} 

getSuggestions(value) { 
    const inputValue = value.trim().toLowerCase(); 
    const inputLength = inputValue.length; 
    return inputLength === 0 ? [] : players.filter(player => 
     (player.NameFirst.toLowerCase().slice(0, inputLength) === inputValue || player.NameLast.toLowerCase().slice(0, inputLength) === inputValue) 
    ); 
} 

getSuggestionValue(suggestion) { // when suggestion selected, this function tells 
    return suggestion.NameFirst; // what should be the value of the input 
} 

renderSuggestion(suggestion) { 
    return (
    <span><Link to={ "/view-player/" + suggestion.id }>{ suggestion.NameFirst + " " + suggestion.NameLast }</Link></span> 
); 
} 

shouldRenderSuggestions(value) { 
     if (value) { 
      return value.trim().length > 0; 
     } 
} 

renderReactable(hitDatas) { 
    return hitDatas.map((hitData) => { 
     // console.log(hitData); 
     if (Number(hitData.playerTeamId) === Number(this.state.selectedTeamID) || this.state.selectedTeamID === null) { 
      return (
       <Tr key={hitData.MaxHic}> 
        <Td column="name" data={hitData.playerNameLast + ', ' + hitData.playerNameFirst} /> 
        <Td column="numHits" data={hitData.numHits} /> 
        <Td column="maxHic" data={Math.round(hitData.MaxHic)} /> 
       </Tr> 
      ); 
     } 
    }); 
} 

renderReactableTwo(allHitDatas) { 
    return allHitDatas.map((hitData) => { 
     // console.log(hitData); 
     if (Number(hitData.playerTeamId) === Number(this.state.selectedTeamID) || this.state.selectedTeamID === null) { 
      return (
       <Tr key={hitData.Hic}> 
        <Td column="name" data={hitData.playerNameLast + ', ' + hitData.playerNameFirst} /> 
        <Td column="hic" data={Math.round(hitData.Hic)} /> 
       </Tr> 
      ); 
     } 
    }); 
} 

dataChangeHelper() { 
    console.log(this.props); 
    const newConfig = { 
     start: this.state.startDate, 
     end: this.state.endDate, 
     team: this.props.team.id 
    }; 

    getDataRange(newConfig) 
    .then((response) => { 
     hitDatas = response.data; 
     this.setState({ 
     hitDatas: hitDatas 
     }); 
    }); 
    getAllHitsData(newConfig) 
    .then((response) => { 
     console.log(response); 
     allHitDatas = response.data; 
     this.setState({ 
     allHitDatas: allHitDatas 
     }); 
    }); 

}

showNewDateRange(newStartDate, newEndDate) { 
    this.setState({ 
    startDate: newStartDate, 
    endDate: newEndDate 
    // showDatePickerControls:false 
    },() => { 
    this.dataChangeHelper(); 
}); 
} 

handleImpactClick(d) { 
console.log(d); 
} 

render() { 
    if (this.state.teams.length === 0 || this.state.players.length === 0) { 
    return (
     <div className="no-data-container"> 
      <div className="no-data-message">We don't have any data for you right now. Would you like 
       to add some players, teams, or devices? 
      </div> 
      <ul className="no-data-links"> 
       <AdminSquare title="PLAYER ADMIN" icon="person" link="/player"/> 
       <AdminSquare title="TEAM ADMIN" icon="group" link="/team"/> 
       <AdminSquare title="DEVICE ADMIN" icon="sd_storage" link="/device"/> 
      </ul> 
     </div> 
    ); 
} 

const { value, suggestions } = this.state; 
const inputProps = { 
    placeholder: 'Search for a player', 
    value, 
    onChange: this.onChange 
}; 

return (
    <div> 
     <div className='admin-table-wrapper'> 
      <div className="homeview-subnav"> 
       <div className="view-title">Team Data</div> 
       <DateRangeComponent 
        startDate={this.state.startDate} 
        endDate={this.state.endDate} 
        onDateChange={(newStartDate, newEndDate) => this.showNewDateRange(newStartDate, newEndDate)} 
       /> 
       <Autosuggest 
        suggestions={suggestions} 
        onSuggestionsUpdateRequested={this.onSuggestionsUpdateRequested} 
        shouldRenderSuggestions={this.shouldRenderSuggestions.bind(this)} 
        getSuggestionValue={this.getSuggestionValue.bind(this)} 
        renderSuggestion={this.renderSuggestion.bind(this)} 
        inputProps={inputProps} 
       /> 
       <button className="retrieve-file-trigger" onClick={this.retrieveFile.bind(this)}><i className='material-icons small file-icon'>file_download</i></button> 
      </div> 
      <div className="top-dashboard-data-container"> 
       <div id="home-scatter-container"> 
        <ScatterPlot 
        data={this.state.allHitDatas} 
        statOneTitle='HIC' 
        location='#home-scatter-container' 
        showScatterPlot={this.state.showScatterPlot} 
        sendHitData={(d) => this.handleImpactClick(d)} 
       /> 
       </div> 
       <DashboardStats 
        impactsRecorded={12456712} 
        devicesActive={27} 
        highestHic={234} 
       /> 
      </div> 
      <div className="table-wrapper"> 
      <div className="table-title">TOP HICS</div> 
      <Table 
       className="table table-dashboard" 
       itemsPerPage={10} 
       pageButtonLimit={5} 
       noDataText="No data available for this filter set" 
       sortable 
       defaultSort={{column: 'hic', direction: 'desc'}}> 
       <Thead> 
        <Th column="name"> 
         <strong className="name-header">NAME</strong> 
        </Th> 
        <Th column="hic"> 
         <strong className="position-header">HIC</strong> 
        </Th> 
       </Thead> 
       { this.renderReactableTwo(this.state.allHitDatas) } 
      </Table> 
      </div> 
      <div className="table-wrapper"> 
      <div className="table-title">MOST HITS</div> 
      <Table 
       className="table table-dashboard" 
       itemsPerPage={10} 
       pageButtonLimit={5} 
       noDataText="No data available for this filter set" 
       sortable 
       defaultSort={{column: 'maxHic', direction: 'desc'}}> 
       <Thead> 
        <Th column="name"> 
         <strong className="name-header">NAME</strong> 
        </Th> 
        <Th column="numHits"> 
         <strong className="position-header"># OF HITS</strong> 
        </Th> 
        <Th column="maxHic"> 
         <strong className="position-header">TOP HIC</strong> 
        </Th> 
       </Thead> 
       { this.renderReactable(this.state.hitDatas) } 
      </Table> 
      </div> 
     </div> 
     </div> 
    ); 
    } 
} 
+0

あなたが好きな場所(好きでない場所でもどこでも)の状態を管理できることに注意してください。グローバル変数またはローカル変数を使用できます。あなたは、あなたの範囲を説明するいくつかのプロパティを持つ小道具で木を下にオブジェクトを渡すことができます。これはローカル変数である可能性があります。このアプローチの主な問題は、標準ではなく拡張性がないことです。 Reduxはこれらの両方を解決します。これが面倒すぎる場合は、[redux-schema](https://www.npmjs.com/package/redux-schema)を使用してください(公開:私が書いた)。 – DDS

答えて

0

です例えば、CoreLayoutのような両方のダッシュボードをカプセル化し、その範囲を小道具として渡すコンポーネントです。

Reduxに切り替えることを検討する価値はありますが、最初は気にならないようですが、実際にそれを実行した後は非常にシンプルです。

+0

それは私の最初のアプローチでしたが、私はそこに、日付範囲と検索を持たないCoreLayoutの管理ビューである子ビューの束があることに気付きました。 – hifilorau

+0

私はreduxでそれを失っていると思う私の減速機を書こうとしています。元のインクリメンタのアクションでは、私は '輸出constのインクリメント= createAction(INCREMENT、(値= 1)=>値);のような行を見ている'しかし、私は '輸出const startDate = createAction(DATE_CHANGE、(value = 1)=> value); 'しかし、ステートメントの値部分をどのように扱うかはわかりません。私はそれが私のコンポーネントの一つでthis.state.startDateから日付を受け取っていると仮定しています。 – hifilorau

+0

ええ、これは私が恩返しで迷子になる場所です。 – hifilorau

関連する問題