응답 (아래)에 레이아웃 구성 요소가 있습니다. this.props.children (또는 이제 childrenWithProps)을 통해이 구성 요소에 주입되는 두 구성 요소에는 사용자가 teh API에서 가져온 데이터 범위를 선택할 수 있도록 만든 날짜 범위 구성 요소가 있습니다. 하나는 플레이어 대시 보드이고 다른 하나는 팀 대시 보드입니다 (기본보기 및 두 번째 코드 블록에 표시됨). 사용자가 팀 대시 보드에 있고 플레이어를 검색하여 해당 플레이어 대시 보드로 이동하면 선택한 날짜 범위 (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>
);
}
}
좋아하는 곳 어디에서나 상태를 관리 할 수 있습니다 (또는 마음에 들지 않는 곳에서도). 글로벌 변수 또는 로컬 변수를 사용할 수 있습니다. 범위를 설명하는 몇 가지 속성을 가진 소도구를 사용하여 개체를 트리 아래로 전달할 수 있습니다. 이것은 지역 변수가 될 수 있습니다. 이 접근 방식의 주요 문제점은 표준이 아니며 확장 할 수 없다는 점입니다. Redux는이 두 가지를 모두 해결합니다. 이것이 너무 번거 롭다면 [redux-schema] (https://www.npmjs.com/package/redux-schema)를 사용하십시오 (공개 : 내가 썼습니다). – DDS