如何解决React.js:从另一个组件调用函数?
我是React.js的新手,对链接两个不同组件中的函数感到困惑。
我正在尝试实现两个组件之间的通信。对我来说,React-leaflet非常困难,因此我在下面使用一种难看的方法来实现此目标:
所以,这是我的父组件,内部有一个表,其中具有“ handleOnRowSelected”功能。我希望我的其他组件(是地图)具有一个功能,因此当用户单击地图组件时,表组件也将触发“ handleOnRowSelected”功能。
如果可以帮助我,请多多帮助!
class Pd extends Component {
state = {
counties:[],allCountyTotal:0,service:[],selectedCounties:[],};
url = 'https://raw.githubusercontent.com/magluie/mappd/master/agegender.csv';
async componentDidMount () {
const response = await axios.get(this.url);
const rows = response.data.split("\n");
console.log(rows[0].split(","));
const counties = [];
const service = [];
let allCountyTotal = 0;
for( let i = 1; i < rows.length; i++) {
const row = rows[i].split(",");
const countyName = row[0];
const atwenty = Number(row[1]);
const athirty = Number(row[2]);
const afourty = Number(row[3]);
const afifty1 = Number(row[4]);
const afifty2 = Number(row[5]);
const asixty1 = Number(row[6]);
const asixty2 = Number(row[7]);
const aseventy1 = Number(row[8]);
const aseventy2 = Number(row[9]);
const aeighty1 = Number(row[10]);
const aeighty2 = Number(row[11]);
const malenum = Number(row[12]);
const femalenum = Number(row[13]);
const total = Number(row[14]);
const serviceName = row[15]
if(countyName !== "" && serviceName !== "") {
counties.push({
name:countyName,total: total,female: femalenum,male: malenum,twenty: atwenty,thirty: athirty,fourty: afourty,fifty1: afifty1,fifty2: afifty2,sixty1: asixty1,sixty2: asixty2,seventy1:aseventy1,seventy2: aseventy2,eighty1: aeighty1,eighty2:aeighty2,service: serviceName,});
}
}
this.setState({
counties:counties,allCountyTotal:allCountyTotal,service:service,});
}
handleOnRowSelected =(countyToUpdate) =>{
const counties =[...this.state.counties];
const countyIndex = counties.findIndex(
(c) => c.name === countyToUpdate.name,(c) => c.female === countyToUpdate.female,(c) => c.male === countyToUpdate.male,(c) => c.twenty=== countyToUpdate.twenty,(c) => c.thirty === countyToUpdate.thirty,(c) => c.fourty === countyToUpdate.fourty,(c) => c.fifty1 === countyToUpdate.fifty1,(c) => c.fifty2 === countyToUpdate.fifty2,(c) => c.sixty1 === countyToUpdate.sixty1,(c) => c.sixty2 === countyToUpdate.sixty2,(c) => c.seventy1 === countyToUpdate.seventy1,(c) => c.seventy2 === countyToUpdate.seventy2,(c) => c.eighty1 === countyToUpdate.eighty1,(c) => c.eighty2 === countyToUpdate.eighty2,);
const county = {
name: countyToUpdate.name,total: countyToUpdate.total,service: countyToUpdate.service,female: countyToUpdate.female,male: countyToUpdate.male,twenty: countyToUpdate.twenty,thirty: countyToUpdate.thirty,fourty: countyToUpdate.fourty,fifty1: countyToUpdate.fifty1,fifty2: countyToUpdate.fifty2,sixty1: countyToUpdate.sixty1,sixty2: countyToUpdate.sixty2,seventy1:countyToUpdate.seventy1,seventy2: countyToUpdate.seventy2,eighty1: countyToUpdate.eighty1,eighty2:countyToUpdate.eighty2,//get the oppisit value
selected: !countyToUpdate.selected,};
counties[countyIndex] = county;
this.setState({counties,selectedCounties: counties.filter((c) =>c.selected),});
};
sortByTotal =(countyA,countyB) =>{
if(countyB.total > countyA.total) return 1;
else if (countyB.total <countyA.total) return -1;
else return 0;
};
handleOnSortByTotal = (event) =>{
this.handleOnSort(event,this.sortByTotal);
};
sortByCountyName =(countyA,countyB) =>{
if(countyA.name > countyB.name) return 1;
else if (countyA.name <countyB.name) return -1;
else return 0;
};
handleOnSortByCountyName = (event) =>{
this.handleOnSort(event,this.sortByCountyName);
};
handleOnSort = (event,sortBy) =>{
event.preventDefault();
const counties = [...this.state.counties]
counties.sort(sortBy);
this.setState({counties});
};
render() {
const { counties,allCountyTotal,selectedCounties}=this.state;
return (
<div>
<MyMap />
<CountyTable
counties = {counties}
onSortByTotal = {this.handleOnSortByTotal}
onSortByCountyName = {this.handleOnSortByCountyName}
onRowSelected = {this.handleOnRowSelected}
/>
</div>
);
}
}
export default Pd;
以下是地图组件:
const DEFAULT_LONGITUDE = 51.903614;
const DEFAULT_LATITUDE = -8.468399;
const mapstyle = {
height: '600px',width: '500px',background:0,marginLeft: '50%',marginTop: '3%',marginBottom: '0.005%'
};
const contystyle = {
fillColor:'darkgreen',weight: 2,opacity: 1,color: 'white',dashArray: '3',fillOpacity: 0.7
}
class MyMap extends React.Component{
constructor(){
super()
this.callHandleOnRowSelected = this.callHandleOnRowSelected.bind(this);
this.handleOnRowSelected = this.handleOnRowSelected.bind(this);
}
callHandleOnRowSelected = () => {
this.handleOnRowSelected()
};
//functions for map
highLightCounty = (event) =>{
event.target.setStyle({
weight:5,color:'white',fillColor:'yellow',fillOpacity:0.6
});
};
//resethighlight county style
resetCountyColor = (event) => {
event.target.setStyle({
fillColor:'darkgreen',fillOpacity: 0.7
});
};
// callHandleOnRowSelected = (event) =>{
// this.handleOnRowSelected()
// };
// functions for features of the map
onEachCountry = (country,layer) => {
const countryName = country.properties.NAME_TAG;
console.log(countryName);
layer.bindPopup(countryName);
layer.on({
mouseover: this.highLightCounty,mouseout: this.resetCountyColor,click: this.callHandleOnRowSelected,});
};
render() {
const Component = ({func}) => {
handleOnRowSelected ()
};
return (
<div>
<Map style={mapstyle}
zoom = {6.5}
center={[latitude,longitude]}
maxZoom={10}
attributionControl={true}
zoomControl={true}
doubleClickZoom={true}
scrollWheelZoom={true}
dragging={true}
animate={true}
easeLinearity={0.35}>
<GeoJSON
style={contystyle}
data = {mapData.features}
onEachFeature = {this.onEachCounty}
/>
</Map>
</div>
);
}
}
解决方法
如果您正在使用redux,则可以考虑使用redux thunk或redux saga。如果不是,请考虑使用redux。 redux的开发人员还提供了redux工具包,可以为您完成redux,react-redux和redux-thunk的布线工作。
Redux React Redux Redux Toolkit Redux Thunk Redux Saga
解释原因:
我相信您的问题与状态管理有关。当源组件的状态发生变化时,您需要一个函数在目标组件中发生(这会更改目标组件的状态)。
在这种情况下,您应该通过父组件连接所有状态(向上移动状态),并通过props提供父组件的功能。
这个问题很常见,通常会在您的反应组件的其他部分发现。
通过引入redux解决了问题的状态部分。如果功能只是改变状态,则问题的功能部分可以通过redux来部分解决,其余的可以通过引入redux saga或redux thunk解决。
,传入父方法作为子组件的支持。您的Map组件应将prop作为构造函数的一部分,然后通过使用prop传递的函数在子组件上调用函数。
// parentComponent.jsx
// something here ...
render() {
return (
<div><ChildComponent onClick={this.onWhatever} /></div>
)
}
// childComponent.jsx
class ChildComponent extends React.Component {
constructor(props) {
super(props);
his.onSomething = this.onSomething.bind(this);
}
onSomething = () => {
const {onClick} = this.props;
onClick();
}
// other things here ...
}
我建议您使用React Hooks,因为您的子组件始终会返回功能组件。除非您对React有一个适当的了解,否则我不会打扰Redux(即使在共享多个事物的状态时,它是一个不错的选择)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。