реактивная ссылка работает только для последнего элемента в массиве - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть родительский компонент и дочерний компонент. Я хочу вызвать функцию моего ребенка в родительском компоненте. Я использую 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 импортируется из моего дочернего компонента, где расположены необходимые функции.

Ребенок:

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;

Функция onClick должна вызываться при нажатии на div в моем заголовке. Но для всех элементов в моем массиве, а не только для последнего ... Функция onClick снова вызывает handleClose () в моем Child.

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Я полагаю, что причина, по которой вы всегда получаете последний экземпляр элемента, в том, что вы итерируете массив и для каждого элемента вы отображаете новый и перезаписываете переменную this.child с новой ссылкой.

Но даже при том, что вы не должны создавать ссылки для каждого элемента элемента. Если вы хотите получить событие onClick, вы должны реализовать это событие в компоненте. Если компонент из сторонней библиотеки, проверьте документацию, чтобы увидеть, как обрабатывать события. Обычно это происходит с событием onClick.

0 голосов
/ 08 ноября 2018

трудно сказать наверняка, не видя больше кода родительского компонента (я думаю, что вы, возможно, что-то вырезали из этого случайно), так что это всего лишь предположение, но вы, вероятно, перезаписываете свой ref при отображении в массив, следовательно, он работает только для последнего элемента. Вы можете найти некоторые решения для этого здесь .

...