我是reactjs的新手,我希望你能指出我正确的方向,因为我遇到了在reactjs中渲染skycons的问题。
在上面的屏幕截图中,我的目标是使用画布显示天气图标但不会显示。
这是我的js代码:daily_weather.js
import React, { Component } from 'react';
import RenderIcons from './icons';
import getNameOfDays from './base';
import axios from 'axios';
export default class DailyWeather extends Component {
constructor(props) {
super(props);
this.state = {
timezone: '',
dailyWeather: {}
};
}
componentDidMount() { // lat = 14.5995 long = 120.9842
axios.get(`https://cors-anywhere.herokuapp.com/https://api.darksky.net/forecast/9d63fb2636b6ed1060be85b7f068f493/-33.865143,151.209900`)
.then((result) => {
this.setState({ timezone: result.data.timezone });
this.setState({ dailyWeather: result.data.daily });
});
}
render() {
const { dailyWeather } = this.state;
if (!dailyWeather.data) {
return <h2>Loading...</h2>
}
const data = dailyWeather.data.map((data, key) => {
return (
<div className="panel" key={`arr${key}`}>
<div className="data-block" >
<div className="weather-icon" >
<RenderIcons icon={data.icon}/>
</div >
</div>
</div>
);
});
return (
<div className="panel-block">
{data}
</div>
);
}
};
icon.js
import React from 'react';
var skycons = new Skycons({ "color": "orange" });
const RenderIcons = ({ icon }) => {
if (!icon) {
return (<h2>Loading...</h2>);
}
if(icon === 'wind') {
skycons.set("wind", Skycons.WIND);
skycons.play();
} else if(icon === 'clear-day') {
skycons.set("clear-day", Skycons.CLEAR_DAY);
skycons.play();
} else if(icon === 'partly-cloudy-day') {
skycons.set("partly-cloudy-day", Skycons.PARTLY_CLOUDY_DAY);
skycons.play();
} else if(icon === 'partly-cloudy-night') {
skycons.set("partly-cloudy-night", Skycons.PARTLY_CLOUDY_NIGHT);
skycons.play();
} else {
console.log('error!');
}
return (<canvas id={`${icon}`} width="64" height="64"></canvas>);
};
export default RenderIcons;
基本上我要做的是将每个data.icons传递给RenderIcons,RenderIcons返回一个显示和播放skycons的画布。
谢谢=)
你需要将canvas元素的引用传递给skycons.set()方法,我不认为Skycons会坚持做出反应的方式。
首先,这是一个简单的例子,展示如何让Skycons使用React:https://codesandbox.io/s/94p3v5ovly
您将要将画布放在render方法中,并使用ref。然后在组件更新后,将画布的引用传递给RenderIcons函数。我害怕这都是未经测试的。但它应该指向正确的方向。见https://reactjs.org/docs/refs-and-the-dom.html和https://reactjs.org/docs/react-component.html#componentdidupdate。
import React from "react";
const Skycons = require("skycons")(window);
class App extands React.Component {
constructor(props) {
super(props);
this.iconRefs = [];
}
render() {
const { dailyWeather } = this.state;
dailyWeather.data.map( (d,k) => {
if (!(k in iconRefs) {
iconRefs[k]= {};
}
});
const data = dailyWeather.data.map((data, key) => {
return (
<div className="panel" key={`arr${key}`}>
<div className="data-block" >
<div className="weather-icon" >
<canvas ref={iconRefs[key]} width="64" height="64"></canvas>
</div >
</div>
</div>
);
});
return (
<div className="panel-block">
{data}
</div>
);
}
componentDidUpdate() {
dailyWeather.data.map((data, key) => {
renderIcons(data, key);
});
}
renderIcons = (icon, key) => {
if (!icon) {
return (<h2>Loading...</h2>);
}
if(icon === 'wind') {
skycons.set(this.iconRefs[key], Skycons.WIND);
skycons.play();
...