Ich habe eine Layout-Komponente in reagieren (unten). Zwei meiner Komponenten, die über this.props.children (oder jetzt childrenWithProps) in diese Komponente injiziert werden, verfügen über eine von mir erstellte Datumsbereichskomponente, mit der der Benutzer den Datenbereich auswählen kann, der aus der API abgerufen wird. Eines ist ein Spieler-Dashboard und eines ist ein Team-Dashboard (Standardansicht und wird im zweiten Codeblock angezeigt). Wenn sich ein Benutzer im Team-Dashboard befindet und einen Player durchsucht und zu diesem Player-Dashboard wechselt, möchte ich den ausgewählten Datumsbereich (der als this.state.startDate und this.state.EndDate gespeichert ist) in das Player-Dashboard übernehmen. und dann umgekehrt. Ich denke, dass dies ein guter Anwendungsfall für Redux ist, aber bis jetzt habe ich es geschafft, nur Requisiten zu passieren und die Redux-Implementierung für den Datumsbereich scheint entmutigend zu sein. Jede Hilfe würde sehr geschätzt werden. Außerdem bin ich neu zu reagieren und weiß, dass ich eine Menge Neuformatierung machen muss.React.js behandelt eine Datumsänderung über Komponenten, die nicht Eltern/Kind sind
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>
);
}
}
Hier ist das Team Armaturenbrett
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>
);
}
}
Beachten Sie, dass Sie den Status überall verwalten können, wo Sie möchten (oder sogar überall, wo Sie nicht mögen). Sie können einfach eine globale Variable oder eine lokale Variable verwenden. Du könntest ein Objekt mit Requisiten mit Eigenschaften, die deine Reichweite beschreiben, durch den Baum ziehen. Dies könnte eine lokale Variable sein. Die Hauptprobleme bei diesem Ansatz sind, dass er nicht standardisiert und nicht erweiterbar ist. Redux löst beides. Wenn das zu viel Aufwand ist, verwenden Sie einfach [redux-schema] (https://www.npmjs.com/package/redux-schema) (Offenlegung: Ich schrieb es). – DDS