Ich baue eine Wetter App mit React & Redux. Ich habe beschlossen, in unbekannte Gewässer als ein Noob zu Reagieren & Redux. Ich teile die Dinge in Präsentationskomponenten und ihre jeweiligen Container, die mit den Daten umgehen. Ich habe jedoch einige Probleme damit meinen Kopf einzuwickeln. Es kommt vielleicht darauf an, wie ich es versuche. Ich bin nur sehr unsicher.React + Redux: Trennung der Präsentation von den Daten
Im Moment habe ich SearchBar
, CurrentWeather
, & Forecast
Komponenten und ein AppContainer
, dass ich diese Komponenten in integrieren bin versucht. Ich habe die SearchBar
Komponente in die AppContainer
bisher integriert und es funktioniert ohne Probleme. Hier bin ich verwirrt. So habe ich dem Container die erforderlichen Aktionen und Komponenten bereitgestellt und der Container wurde connected
. Wenn der Benutzer eine Suche durchführt, wird der API-Aufruf durchgeführt und der Status wird über die Reduzierungen aktualisiert.
Die Daten sollten über mapStateToProps
jetzt korrekt sein?
Wie kann ich die Daten verwenden, nachdem der Benutzer die Aktion ausgeführt hat, aber nicht beim ersten Rendern verwendet wird? Wenn AppContainer
diese drei Komponenten rendert, werde ich offensichtlich Requisiten an sie übergeben, damit sie rendern und funktionieren, wie sie erwartet werden. Ich denke, dass hier ein Lebenszyklus verwendet werden könnte. Ich bin mir nur unsicher, was oder wie ich sie verwenden soll. Mein Code für die AppContainer
, SearcBar
, & CurrentWeather
sind unten. CurrentWeather
& Forecast
sind fast identisch (nur verschiedene Daten von verschiedenen Endpunkten für die API zur Verfügung stellen), also habe ich es nicht zur Verfügung gestellt. Ich habe auch die Aktionen oder Reduzierungen nicht zur Verfügung gestellt, weil ich weiß, dass sie gut funktionieren, bevor ich mich dazu entschloss, diesen Refactor zu versuchen. Vielleicht brauche ich mehr als einen Container, um das durchzuziehen? Jeder Rat oder jede Richtung würde sehr geschätzt werden, danke allen und eine gute Nacht.
** Haben Sie eine Nebenfrage: unter _weatherSearch
habe ich event.preventDefault();
, weil die SearchBar
ein Formularelement ist. Muss ich das überhaupt bereitstellen? Wenn event
ist nicht das, was passiert ist, aber die term
Ich denke nein. Die event
verwendet wird, wie unten in Form Element SearchBar
gesehen:
onSubmit={event => getWeather(event.target.value)}
App Container:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchCurrentWeather, fetchForecast } from '../actions/actions';
import SearchBar from '../components/SearchBar';
import CurrentWeather from '../components/CurrentWeather';
class AppContainer extends Component {
_weatherSearch(term) {
event.preventDefault();
// Here is where we go to fetch weather data.
this.props.fetchCurrentWeather(term);
this.props.fetchForecast(term);
}
render() {
const getWeather = term => {this._weatherSearch(term);};
return (
<div className="application">
<SearchBar getWeather={getWeather}/>
<CurrentWeather />
</div>
);
}
}
const mapStateToProps = ({ current, forecast }) => {
return {
current,
forecast
}
}
export default connect(mapStateToProps,
{ fetchCurrentWeather, fetchForecast })(AppContainer);
SearchBar:
import React from 'react';
const SearchBar = ({ getWeather }) => {
return(
<form className='input-group' onSubmit={event => getWeather(event.target.value)}>
<input
className='form-control'
placeholder='Search a US City' />
<span className='input-group-btn'>
<button className='btn btn-secondary' type='submit'>Submit</button>
</span>
</form>
);
}
export default SearchBar;
DasaktuelleWetter: * Hinweis: Ich habe nicht entfernt von der Logik oder Datenverarbeitung von CurrentWeather
noch so ist es nicht refacto rot zu einer nur zur Präsentation gehörigen Komponente.
import React, {Component} from 'react';
import {connect} from 'react-redux';
import {unitConverter} from '../conversions/conversions_2.0';
export class CurrentWeather extends Component {
_renderCurrentWeather(cityData) {
const name = cityData.name;
const {temp, pressure, humidity} = cityData.main;
const {speed, deg} = cityData.wind;
const {sunrise, sunset} = cityData.sys;
return (
<tr key={name}>
<td>{unitConverter.toFarenheit(temp)} F</td>
<td>{unitConverter.toInchesHG(pressure)}"</td>
<td>{humidity}%</td>
<td>{unitConverter.toMPH(speed)}mph {unitConverter.toCardinal(deg)}</td>
</tr>
);
}
render() {
let currentWeatherData = [];
if (this.props.current) {
currentWeatherData = this.props.current.map(this._renderCurrentWeather);
}
return (
<table className="table table-reflow">
<thead>
<tr>
<th>Temperature</th>
<th>Pressure</th>
<th>Humidity</th>
<th>Wind</th>
</tr>
</thead>
<tbody>
{currentWeatherData}
</tbody>
</table>
);
}
}
function mapStateToProps({current}) {
return {current};
}
export default connect(mapStateToProps)(CurrentWeather);
tut Ihr 'AppWrapper' die Logik für die Präsentations-Komponenten enthalten dann und Sie passieren nur' props' zu den untergeordneten Komponenten nach unten wiedergegeben wird in 'AppContainer'? – rockchalkwushock
Ich denke, wo Sie die Logik platzieren, ist eine bevorzugte Sache. Ich dachte entlang der Linien, wo alles genau so war wie vorher, außer dass du die asynchronen Aktionen ausführst, sie in "AppWrapper" steckst und den "Zustand" dieser Aktionen in eine Requisite verwandelst. Zusammenfassung: Wrapper enthält asynchrone Aktionen, Container enthält Logik, Komponenten enthalten jsx. – omul