I am having a parent component and a child component. I want to call a function from my child in my parent component. I am using ref and it works fine, but just for my last element in my array...
Parent:
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 is imported from my Child component, where the needed functions are located.
Child:
componentDidMount() {
this.props.onRef(this)
}
componentWillUnmount() {
this.props.onRef(undefined)
}
handleClose = () => {
this.setState({ open: false });
this.props.triggerClose();
}
It seems like that the ref works only for the last element in my items[]...
Do you have any suggestions on how to make it work for every element in my array?
Here is my full Parent Compoenent, could be heldpful. Still have no clue how to set the ref...
Parent (complete):
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;
The onClick function schould be called when clicked on the div in my header. But for all elements in my array and not just for the last one.... The onClick function calls again the handleClose() in my Child.