我有一个父组件和一个子组件。我想在我的父组件中从我的孩子那里调用一个函数。我正在使用ref,并且工作正常,但仅用于数组中的最后一个元素...
父母:
onClick = () => {
this.child.handleClose() // do stuff
}
var items = [];
tracks.filter(searchingFor(term)).map(function(title, i)
{
items.push(
<div >
<ItemViewAll
onRef={ref => (this.child = ref)}
triggerOpen={this.handleOpenParent.bind(this)}
triggerClose={this.handleCloseParent.bind(this)}
key={title.id}
title={title.title}
/>
</div>
);
}, this);
ItemViewAll从我的Child组件(所需功能所在的位置)中导入。
孩子:
componentDidMount() {
this.props.onRef(this)
}
componentWillUnmount() {
this.props.onRef(undefined)
}
handleClose = () => {
this.setState({ open: false });
this.props.triggerClose();
};
似乎ref仅适用于我项目中的最后一个元素[] ...
您对如何使其适用于数组中的每个元素有任何建议?
这是我完整的家长资料,可以保留。仍然不知道如何设置参考...
父母(完整):
const { scaleDown } = transitions;
function searchingFor(term){
return function(x){
return x.title.toLowerCase().includes(term.toLowerCase()) ||
x.body.toLowerCase().includes(term.toLowerCase());
}
}
class ViewAll extends React.Component{
constructor(props){
super(props);
this.state = {
term: '',
mounted: false,
tracks: [],
hasMoreItems: true,
}
this.searchHandler = this.searchHandler.bind(this);
this.focus = this.focus.bind(this);
}
loadContent() {
var requestUrl = this.props.url;
fetch(requestUrl).then((response)=>{
return response.json();
}) .then((tracks)=>{
this.setState({ tracks: this.state.tracks.concat(tracks)});
}).catch((err)=>{
console.log("There has been an error");
});
}
componentDidMount() {
var requestUrl = this.props.url;
fetch(requestUrl).then((response)=>{
return response.json();
}) .then((data)=>{
this.setState({tracks : data});
}).catch((err)=>{
console.log("There has been an error");
});
window.scrollTo(0, 0);
this.focus();
}
handleOpenParent(){
this.setState({ show: true })
}
handleCloseParent(){
this.setState({ show: false})
}
searchHandler(event){
this.setState({term: event.target.value
})
}
focus() {
this.textInput.focus();
}
onClick = () => {
this.child.handleClose() // do stuff
}
render() {
const {term, data, tracks} = this.state;
const loader = <div className="loader"></div>;
var items = [];
tracks.filter(searchingFor(term)).map(function(title, i)
{
items.push(
<div>
<MuiThemeProvider>
<Paper style={{ borderRadius: "2em",
background: 'linear-gradient(to right, #82f2da 30%, white
100%)'
}} zDepth={1} >
<ItemViewAll
onRef={ref => (this.child = ref)}
triggerOpen={this.handleOpenParent.bind(this)}
triggerClose={this.handleCloseParent.bind(this)}
key={title.id}
title={title.title}
score={title.vote_average}
overview={title.body}
backdrop={title.image}
description={title.description}
messenger={title.messenger}
twitter={title.twitter}
discord={title.discord}
slack={title.slack}
kik={title.kik}
telegram={title.telegram}
/>
</Paper>
</MuiThemeProvider>
</div>
);
}, this);
return (
<div>
<header className="Header">
{this.state.show &&
<div style={{height: 50, width: 50, background: 'red'}} onClick=
{this.onClick}>
</div>
}
</header>
<div>
<Media query="(max-width: 599px)">
{matches =>
matches ? (
<div style={{marginTop: 100}}>
<div style={{width: '90%', marginLeft: 'auto', marginRight:
'auto', marginBottom: 50 }}>
<MuiThemeProvider>
<TextField
hintText="Welcher Bot darf es sein?"
type="Text"
onChange={this.searchHandler}
value={term}
fullWidth={true}
underlineFocusStyle={{borderColor: '#82f2da',
borderWidth: 3}}
underlineStyle={{borderColor: '#82f2da', borderWidth:
1.5, top: '40px'}}
hintStyle={{fontSize: 30, fontFamily: 'Anton'}}
inputStyle={{fontSize: 30, fontFamily: 'Anton'}}
ref={(input) => { this.textInput = input; }}
style={{caretColor: '#82f2da'}}
/>
</MuiThemeProvider>
</div>
</div>
) : (
<div style={{marginTop: 130}}>
<div style={{width: '80%', marginLeft: 'auto',
marginRight: 'auto', marginBottom: 70 }}>
<MuiThemeProvider>
<TextField
hintText="Welcher Bot darf es sein?"
type="Text"
onChange={this.searchHandler}
value={term}
fullWidth={true}
underlineFocusStyle={{borderColor: '#82f2da',
borderWidth: 3}}
underlineStyle={{borderColor: '#82f2da',
borderWidth: 1.5, top: '50px'}}
hintStyle={{fontSize: 40, fontFamily: 'Anton'}}
inputStyle={{fontSize: 40, fontFamily: 'Anton'}}
ref={(input) => { this.textInput = input; }}
style={{caretColor: '#82f2da'}}
/>
</MuiThemeProvider>
</div>
</div>
)
}
</Media>
<Media query="(max-width: 599px)">
{matches =>
matches ? (
<InfiniteScroll
pageStart={1}
loadMore={this.loadContent.bind(this)}
hasMore={this.state.hasMoreItems}
loader={loader}
initialLoad={false}
>
<StackGrid
columnWidth={180}
gutterHeight={10}
gutterWidth={10}
duration={1500}
monitorImagesLoaded={true}
easing={easings.quadInOut}
appear={scaleDown.appear}
appeared={scaleDown.appeared}
enter={scaleDown.enter}
entered={scaleDown.entered}
leaved={scaleDown.leaved}
>
{items}
</StackGrid>
</InfiniteScroll>
) : (
<InfiniteScroll
pageStart={10}
loadMore={this.loadContent.bind(this)}
hasMore={this.state.hasMoreItems}
loader={loader}
initialLoad={true}
>
<StackGrid
columnWidth={180}
gutterHeight={80}
gutterWidth={80}
duration={1500}
monitorImagesLoaded={true}
easing={easings.quadInOut}
appear={scaleDown.appear}
appeared={scaleDown.appeared}
enter={scaleDown.enter}
entered={scaleDown.entered}
leaved={scaleDown.leaved}
>
{items}
</StackGrid>
</InfiniteScroll>
)
}
</Media>
</div>
</div>
)
}
}
export default ViewAll;
在我的标题中的div上单击时,应调用onClick函数。但是对于我数组中的所有元素,而不仅仅是最后一个元素。...onClick函数再次调用Child中的handleClose()。
答案 0 :(得分:1)
我相信总是得到最后一个元素实例的原因是,因为您正在迭代一个数组,并且对于每个项目,您都会渲染一个新的并使用。的新引用覆盖this.child变量。
但是,尽管如此,您也不应该为元素的每个项目创建一个引用。如果要获取onClick事件,则必须在component上实现此事件。如果该组件来自第三方库,请查看文档以了解如何处理事件。通常,它与onClick事件有关。
答案 1 :(得分:0)
很难确定而没有看到更多的父组件代码(我认为您可能不小心从中切出了一些东西),所以这只是一个猜测,但是您可能会在映射到数组时覆盖您的ref,因此它只能工作最后一个元素。您可以找到关于该here的一些解决方案。