Arrays reactjs ref仅适用于数组中的最后一个元素
我有一个父组件和一个子组件。我想从父组件中的子组件调用函数。我正在使用ref,它工作得很好,但只针对数组中的最后一个元素 家长:Arrays reactjs ref仅适用于数组中的最后一个元素,arrays,reactjs,parent-child,ref,Arrays,Reactjs,Parent Child,Ref,我有一个父组件和一个子组件。我想从父组件中的子组件调用函数。我正在使用ref,它工作得很好,但只针对数组中的最后一个元素 家长: onClick = () => { this.child.handleClose() // do stuff } var items = []; tracks.filter(searchingFor(term)).map(function(title, i) { items.push( <div &g
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);
componentDidMount() {
this.props.onRef(this)
}
componentWillUnmount() {
this.props.onRef(undefined)
}
handleClose = () => {
this.setState({ open: false });
this.props.triggerClose();
};
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;
似乎ref只适用于我的items[]中的最后一个元素
对于如何使它对数组中的每个元素都有效,您有什么建议吗
这是我父母的全部心意,可以帮助我。仍然不知道如何设置参考
家长(完整):
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);
componentDidMount() {
this.props.onRef(this)
}
componentWillUnmount() {
this.props.onRef(undefined)
}
handleClose = () => {
this.setState({ open: false });
this.props.triggerClose();
};
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;
const{scaleDown}=transitions;
函数搜索(术语){
返回函数(x){
返回x.title.toLowerCase().includes(term.toLowerCase())|
x、 body.toLowerCase()。包括(term.toLowerCase());
}
}
类ViewAll扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
术语:“”,
错,,
轨道:[],
hasMoreItems:是的,
}
this.searchHandler=this.searchHandler.bind(this);
this.focus=this.focus.bind(this);
}
loadContent(){
var requestUrl=this.props.url;
获取(请求URL)。然后((响应)=>{
返回response.json();
})。然后((曲目)=>{
this.setState({tracks:this.state.tracks.concat(tracks)});
}).catch((错误)=>{
log(“出现错误”);
});
}
componentDidMount(){
var requestUrl=this.props.url;
获取(请求URL)。然后((响应)=>{
返回response.json();
})。然后((数据)=>{
this.setState({tracks:data});
}).catch((错误)=>{
log(“出现错误”);
});
滚动到(0,0);
这是focus();
}
handleOpenParent(){
this.setState({show:true})
}
handleCloseParent(){
this.setState({show:false})
}
searchHandler(事件){
this.setState({term:event.target.value
})
}
焦点(){
this.textInput.focus();
}
onClick=()=>{
this.child.handleClose()//做事
}
render(){
const{term,data,tracks}=this.state;
常量加载器=;
var项目=[];
tracks.filter(搜索(术语)).map(函数(标题,i)
{
推(
(this.child=ref)}
triggerOpen={this.handleOpenParent.bind(this)}
triggerClose={this.handleCloseParent.bind(this)}
key={title.id}
title={title.title}
分数={头衔.投票_平均数}
概述={title.body}
背景={title.image}
description={title.description}
messenger={title.messenger}
twitter={title.twitter}
discord={title.discord}
slack={title.slack}
kik={title.kik}
电报={title.telegram}
/>
);
},这个);
返回(
{this.state.show&&
}
{匹配=>
火柴(
{this.textInput=input;}}
style={{caretColor:'#82f2da'}}
/>
) : (
{this.textInput=input;}}
style={{caretColor:'#82f2da'}}
/>
)
}
{匹配=>
火柴(
{items}
) : (
{items}
)
}
)
}
}
导出默认的ViewAll;
单击我的标题中的div时,将调用onClick函数。但是对于数组中的所有元素,而不仅仅是最后一个。。。。onClick函数再次调用我的孩子中的handleClose()。如果没有看到更多的父组件代码,很难说是肯定的(我认为您可能意外地从中剪切了一些内容),因此这只是一个猜测,但您可能在映射数组时覆盖了ref,因此它只对最后一个元素起作用。您可以找到一些解决方案。我相信您总是得到最后一个元素实例的原因,这是因为您正在迭代一个数组,并且对于每个项目,您都会呈现一个新的并使用新的引用覆盖this.child变量
但即使如此,您也不应该为元素的每个项创建一个ref。如果要获取onClick事件,必须在组件上实现此事件。如果组件来自第三方库,请查看文档以了解如何处理事件。通常是onClick事件。谢谢你的回答,我在帖子中添加了完整的父组件。这对你有帮助吗?我也有同样的问题,你找到解决办法了吗?