Reputation: 157
I'm trying to create my own pagination (without using a package), but I can't get it to work.
I'm wondering if it has something to do with how I'm copying my arrays, but I'm not really sure.
class InsightSearchResults extends Component {
state = {
start: 0,
end: 2,
insightsArrayOriginal: [],
copiedArr: []
}
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.insightList[0]) {
this.setState({
insightsArrayOriginal: nextProps.insightList[0].insights,
copiedArr: nextProps.insightList[0].insights.splice(this.state.start, this.state.end)
})
}
}
clickNext = () => {
let copied = [...this.state.insightsArrayOriginal];
this.setState({
start: this.state.start + 2,
end: this.state.end + 2
}, () => {
this.setState({
copiedArr: copied.splice(this.state.start, this.state.end)
})
})
}
clickPrev = () => {
this.setState({
start: this.state.start - 2 < 0 ? 0 : this.state.start - 2,
end: this.state.end - 2
})
}
render() {
const { copiedArr } = this.state;
return (
<div style={{padding: "1.5rem"}}>
{copiedArr ? copiedArr.map(insight => (
<div>
<Grid className="insight_result_block">
<Col className="insight_results_col2" span="10">
<div>
<h4>Hello</h4>
<p>{insight.insightDesc}</p>
</div>
</Col>
</Grid>
<hr className="bottom_hr_insight" />
</div>
)) : <p>loading...</p> }
<button onClick={this.clickPrev}>Prev</button>
<button onClick={this.clickNext}>Next</button>
</div>
)
}
}
I haven't really worked on the "prev" part yet. I'm just trying to get the "next" to work for now...
Upvotes: 2
Views: 1515
Reputation: 1567
There are two problems:
UNSAFE_componentWillReceiveProps
is not called on initial render. From the docs:React doesn’t call UNSAFE_componentWillReceiveProps() with initial props during mounting. It only calls this method if some of component’s props may update. Calling this.setState() generally doesn’t trigger UNSAFE_componentWillReceiveProps().
splice
mutates the original array, use slice
instead. See this question.So you can move the content of UNSAFE_componentWillReceiveProps
to componentDidMount
and componentDidUpdate
componentDidMount() {
this.updateState();
}
componentDidUpdate() {
// check if a change in props has caused the rerender
// or you will get infinite rerenders if one state update causes the next one
if (
this.props.insightList[0] &&
this.props.insightList[0].insights !== this.state.insightsArrayOriginal
) {
this.updateState();
}
}
These functions don't receive a parameter: replace nextProps
parameter with this.props
; and change all splice
occurrences with slice
.
updateState() {
if (this.props.insightList[0]) {
this.setState({
insightsArrayOriginal: this.props.insightList[0].insights,
copiedArr: this.props.insightList[0].insights.slice( . // <-here
this.state.start,
this.state.end
)
});
}
}
clickNext = () => {
let copied = [...this.state.insightsArrayOriginal];
this.setState({ start: this.state.start + 2, end: this.state.end + 2 },
() => {
this.setState({
copiedArr: copied.slice(this.state.start, this.state.end) // <- and here
});
}
);
};
Also, based on this code sample alone, you could entirely remove insightsArrayOriginal
from your state
and use it from props
, but this may change if you plan to expand the functionality.
Upvotes: 1