2017-08-16 40 views
16

Mam tabelę - nazwijmy ją tabelą 1. Po kliknięciu na wiersz w tabeli 1 wyświetlana jest inna tabela, nazwijmy ją jedną tabelą 2. Tabela 2 wyświetla dane dotyczące kliknięty wiersz w tabeli 1. Czasami pionowy zwój musi być wyświetlony w tabeli 2, a czasami nie - zależy od liczby wierszy. trzeba rozwiązać: jest niechciany przejście granicy, gdy nie jest wyświetlany przewijania:Zaktualizuj proppeda/stan podążający za div onclick

enter image description hereenter image description here. Pomysł rozwiązania: "zmień margines prawy" zgodnie z warunkami, które wskazują, czy zwój się kończy, czy też nie. Zapisz wynik tego warunku w elemencie Redux prop: element.scrollHeight> element.clientHeight || element.scrollWidth>
element.clientWidth

Problem: Próbuje zaktualizować wyświetlaną/non-wyświetlanie przewijania do Redux rekwizyt z różnych wydarzeń, takich jak reagować componentDidMount, componentWillReceiveProps, CopmponentDidUpdate (ustaw stan powoduje pętlę infinte tutaj) i od zdarzenia click.Tried, aby użyć forceUpdate() po ustawieniu rekwizytów w Redux.

Kiedy console.log na konsoli w chrome (F12), jedyny wynik, który jest poprawnie skorelowany z wyświetlaniem/brakiem wyświetlania paska przewijania, pochodzi z elementu componentDidUpdate i nie odzwierciedla się w rekwizytce redux (isoverflown zwraca true, redux this.props.scrollStatus i this.state.scrollStatus są fałszywe). Nie podoba ci się również użycie document.getElementById dla div, który zawiera wiersze, ponieważ łamie manipulację domem z poziomu rekwizytów i stanów, ale na razie nie znalazł innego rozwiązania.

Konsola F12 podczas wyświetlania paska przewijania: enter image description here

Konsola F12, gdy wyświetlany jest pasek przewijania nie: enter image description here.

Reszta kodu:

1) działanie:

 export function setScrollStatus(scrollStatus) { 
 
     return { 
 
       type: 'SET_SCROLL_STATUS', 
 
       scrollStatus: scrollStatus 
 
     }; 
 
     }

2) Reduktor

 export function scrollStatus(state = [], action) { 
 
      switch (action.type) { 
 
       case 'SET_SCROLL_STATUS': 
 
        return action.scrollStatus; 
 
       default: 
 
        return state; 
 
     } 
 
    }

3) Page.js (kliknij na zdjęcie, by zobaczyć kod)

enter image description here

import {setScrollStatus} from '../actions/relevantfilename'; 

function isOverflown(element) { 
    return element.scrollHeight > element.clientHeight ||element.scrollWidth > element.clientWidth; 
} 

class SportPage extends React.Component { 
    constructor(props) { 
     super(props); 
     this.state = initialState(props); 
     this.state = { 
      scrolled:false, 
      scrollStatus:false}; 

     componentDidUpdate() { 
      console.log("1 isoverflown bfr redux-this.props.setScrollStatus inside componentDidUpdate",isOverflown(document.getElementById('content'))); 
      //redux props 
      this.props.setScrollStatus(isOverflown(document.getElementById('content'))); 
      console.log("2 isoverflown aftr redux-this.props.setScrollStatus inside componentDidUpdate",isOverflown(document.getElementById('content'))); 
      //redux props 
      this.props.scrollStatus ? console.log (" 3 this.props.scrollStatus true inside componentDidUpdate") : console.log("this.props.scrollStatus false inside componentDidUpdate"); 
      console.log ("4 state scrollstatus inside componentDidUpdate" , this.state.scrollStatus) 
     } 

     componentDidMount(){ 
      console.log("3 isoverflown bfr set",isOverflown(document.getElementById('content'))); 
      this.props.setScrollStatus("set inside didMount", isOverflown(document.getElementById('content'))); 
      console.log("4 isoverflown aftr set didMount",isOverflown(document.getElementById('content'))); 
      this.props.scrollStatus ? console.log ("scrollStatus true") : console.log("scrollStatus false"); 
      console.log ("state scrollstatus inside didMount" , this.state.scrollStatus) 
     } 

     render() { 
      <div style={{overflowY:'scroll',overflowX:'hidden',height:'50vh',border:'none'}}> 
      { 
      this.props.rowData.map((row,index)=> 
      <div style={{ display: 'flex',flexWrap: 'wrap', border:'1px solid black'}} 
      onClick={ e => { this.setState({ selected: index, detailsDivVisible: true,scrolled:isOverflown(document.getElementById('content')), 
      scrollStatus:isOverflown(document.getElementById('content')) }, 
      this.props.setScrollStatus(isOverflown(document.getElementById('content'))),this.forceUpdate(),console.log ("onclick this.state.scrollStatus", this.state.scrollStatus), 
      console.log ("onclick pure funtion", isOverflown(document.getElementById('content')))); 

      const mapDispatchToProps = (dispatch) => { 
       return { 
       setScrollStatus: function (scrollStaus) {dispatch (setScrollStatus(scrollStaus))}, 
      }; 
     }; 
     export default connect(mapStateToProps, mapDispatchToProps)(Page); 
+0

Czy kod somowhere jak github lub tak. Będzie musiał uruchomić projekt, aby zobaczyć problem. –

+0

świetnie, że możesz go rozwiązać. –

+0

Dziękujemy za chęć pomocy. – Dani

Odpowiedz

1

Dziękuję za odpowiedź. Jednak rozwiązano go w inny sposób, który nie dotyczy cyklu życia/zdarzeń:

1) Oblicz wysokość przewijanego przewyższaj wysokość pojedynczego wiersza o liczbę wyświetlanych elementów (arr.Długość ARR pochodzi JSON)

2) ustalenie maksymalnego wysokość zwoju do potrzebnej wartości

3) Ustawienie maksymalnej wysokości zawartości być obliczona wysokość:

Wynik jest zwojem wyświetlającym cały czas z prawidłową wysokością. To rozwiązało problem z wcięciami.

\t 
 
<div style={{overflowY:'auto', marginRight: '18px',zIndex:'1000',borderBottom:'1px solid black',borderRight:'1px solid black', height: this.props.rowData[this.state.selected].rowItemsList.length * singleRowHeight + 'px', maxHeight:'100px' }}> 
 

 
<div style={{ width:'inherit', maxHeight:this.props.this.props.rowData[this.state.selected]‌​.rowItemsList.length * singleRowHeight + 'px' }}>

+1

To pytanie wciąż pojawia się jako bez odpowiedzi w wyszukiwaniu. Czy widzisz, czy możesz zaakceptować własną odpowiedź? https://stackoverflow.com/help/self-answer – jonahe

+0

FYI, nie powinieneś używać obiektów stylu inline, ponieważ zmusi to ponowne renderowanie twojego drzewa podrzędnego, ponieważ nowe wystąpienie obiektu jest tworzone za każdym razem. Skuteczność tego działania zależy od wielkości drzewa. Ogólnie najlepszą praktyką jest przypisanie jej do zmiennej w składniku i użycie jej w elemencie div. – tgallacher

0

Pozwala to uprościć. Wystarczy, że wyślesz reduktor za każdym razem, gdy ktoś kliknie w div. Proszę znaleźć fragment kodu, który jest użyteczny, proszę przejść przez komentarze.

//import store from "./store/directory" - update this to ur store 
 
let DOMObject = document.getElementById("id1"); //dom reference i did it based on ID its up to u to refer how u like it 
 
//call back happens each time onclick event is triggered 
 
DOMObject.onclick =()=> { 
 
/* store.dispatch(
 
{ 
 
type:"reducer to invoke", 
 
data:"the data to update on click" 
 
} 
 
); 
 
*/ 
 
//uncomment above and update to your requirement 
 
console.log("clicked - Please update the dispatch event to you requirement"); 
 

 
}
#id1 { 
 
padding :100px 150px 100px 80px; 
 
background-color: lightblue; 
 
}
<div id="id1"> 
 
DIV AREA - clcik 
 
</div>