I have 3 tabs as below:
ALL|Top100|Spam
At first load page, ALL is called and I receive 257 return records, then I click tab "Spam" and I receive 11 return records. All is ok.
But when my current page is "Spam" then I click tab "ALL", I also receive 11 return records. It wrong! The result is must 257 records.
After debug, I found "componentWillReceiveProps" in this case is called one time only, while at first load page it called 2 times. Lead to the state on Reducer is not update.
Please help me.
Thank you all
Here my code:
PostPage
/**
* Created by admin on 7/7/17.
*/
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import * as combineActions from '../../actions/index';
import { bindActionCreators } from 'redux';
import PostFilter from './PostFilter';
import PaginationView from '../common/PaginationView';
import { MODAL_TYPES } from '../../const';
import List from '../common/List';
import { I18n } from 'react-redux-i18n';
import toastr from 'toastr';
import moment from 'moment';
// import { showModal } from '../../actions/modalAction';
import PostForm from './PostForm';
const Translate = require('react-redux-i18n').Translate;
class PostPage extends Component {
constructor(props, context) {
super(props, context);
this.state = {
currentPage: props.paging.currentPage,
displayMode: props.displayMode,
searchKey: '',
fromDate: '',
toDate: '',
flgRng: '',
category: '',
};
}
handleChangeDate = (dateName, dateValue) => {
let fromDate, toDate;
if (dateName === 'fromDate') {
fromDate = dateValue;
this.setState({
fromDate,
})
}else{
toDate = dateValue;
this.setState({
toDate,
})
}
}
handlelChangeFilter = (event) => {
this.setState({
[event.target.name]: event.target.value
});
}
handleSearch = () => {
const { searchKey, category } = this.state;
let { flgRng, fromDate, toDate } = this.state;
const params = {};
if(this.validate(fromDate, toDate) ===false)
{
return;
}
if (category) {
params['category.id'] = category;
}
let fD, tD;
if(fromDate){
fD = this.formatDate(fromDate);
flgRng = "1";
}else{
flgRng = "";
}
if(toDate){
tD = this.formatDate(toDate);
}
this.setState({
flgRng
})
this.props.actions.fetchPosts({ SearchKey: searchKey, FromDate: fD, ToDate: tD, FlgRng: flgRng, Query: JSON.stringify(params), Mode: this.props.displayMode})
}
handleShowFormNew = () => {
this.props.actions.showModal(
MODAL_TYPES.POST_NEW,
Object.assign(
{
title: I18n.t('common.delete_confirm'),
message: <PostForm />,
type: 'delete_confirm',
handleOK: () => {},
},
this.props,
),
);
}
validate = (fromDate, toDate) => {
if(!fromDate && toDate){
toastr.error(I18n.t('post.msg_fdate'));
return false;
}
if(fromDate && (fromDate === null || fromDate === "" || Date.parse(fromDate) === NaN)){
toastr.error(I18n.t('post.msg_format_fdate'));
return false;
}
if(toDate && (toDate === null || toDate === "" || Date.parse(toDate) === NaN)){
toastr.error(I18n.t('post.msg_format_tdate'));
return false;
}
if(fromDate && toDate){
fromDate = new Date(fromDate)
toDate = new Date(toDate)
if(fromDate > toDate){
toastr.error(I18n.t('post.msg_compare_fdtd'));
return false;
}
}
}
formatDate = (date) => {
var d = new Date(date),
month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = d.getFullYear();
if (month.length < 2) month = '0' + month;
if (day.length < 2) day = '0' + day;
return [month, day, year].join('-');
}
componentWillMount() {
this.props.actions.setCurrentPage(1);
this.props.actions.fetchPosts();
this.props.actions.fetchCategories();
}
deletePost = (item) => {
this.props.actions.showModal(MODAL_TYPES.CONFIRM_MODAL, Object.assign({
title: I18n.t('common.delete_confirm'),
message: (<Translate value="members.delete_confirm_msg" name={item.content} dangerousHTML />),
type: 'delete_confirm',
handleOK: () => {
this.props.actions.deletePost(item._id)
.then(rs => {
this.props.actions.hideModal();
this.props.actions.triggerRefresh();
toastr.success(I18n.t('post.post_deleted_success'));
}).catch(error => {
this.props.actions.hideModal();
toastr.error(error.message || error);
});
}
}, this.props));
}
componentWillReceiveProps(nextProps) {
const triggerRefresh = this.props.triggerRefresh;
let params = {};
if((this.state.displayMode !== nextProps.displayMode)||(this.state.currentPage !== nextProps.paging.currentPage || triggerRefresh !== nextProps.triggerRefresh)){
this.setState({ currentPage: nextProps.paging.currentPage, displayMode: nextProps.displayMode, searchKey: this.state.searchKey, fromDate: this.state.fromDate, toDate: this.state.toDate, flgRng: this.state.flgRng, category: this.state.category});
if(this.state.category){
params['category.id'] = this.state.category;
}
let fromDate, toDate, flgRng;
if(this.validate(this.state.fromDate, this.state.toDate) ===false)
{
return;
}
if(this.state.fromDate){
fromDate = this.state.fromDate.format("MM-DD-YYYY");
flgRng = "1"
}
if(this.state.toDate){
toDate = this.state.toDate.format("MM-DD-YYYY");
}
this.props.actions.fetchPosts({PageNumber: nextProps.paging.currentPage , SearchKey: this.state.searchKey, FromDate: fromDate, ToDate: toDate, FlgRng: flgRng, Query: JSON.stringify(params), Mode: nextProps.displayMode})
}
}
render() {
const {posts, actions, triggerRefresh, categories, displayMode} = this.props;
const {currentPage} = this.state;
let data = []
let listOptions = {}
if(posts.items.length > 0 && posts.items[0].spamRecs && displayMode ==='spam'){
data = posts.items.length > 0 ? posts.items.map(key => {
key.name = key.author? `${key.author.firstName} ${key.author.lastName}`: '';
key.categoryName = key.category ? key.category.name : '';
key.createdDate = moment(key._created).format('MM/DD/YYYY');
key.reportedDate = key.spamRecs ? moment(key.spamRecs['_created']).format('MM/DD/YYYY') : "";
key.numberReport = key.spamRecs ? key.spamRecs.length : 0
return key;
}): []
listOptions = {
headers: [I18n.t('common.title'), I18n.t('post.category'), I18n.t('post.author'), I18n.t('post.created_date_time'), I18n.t('post.number_report'), I18n.t('post.reported_date'), I18n.t('common.action')],
data: {
items: data,
mapping: ['content', 'categoryName','name', 'createdDate', 'numberReport', 'reportedDate', 'action'],
align:["","","","","center","",""],
render: [
{
key: "content",
render: (item) => {
return <div className="overflow" style={{ width: '180px'}}>{item.content}</div>
}
},
{
key: "categoryName",
render: (item) => {
return <div className="overflow" style={{ width: '140px'}}>{item.categoryName}</div>
}
},
{
key: "name",
render: (item) => {
return <div className="overflow" style={{ width: '60px'}}>{item.name}</div>
}
}
],
},
params: {url: '/posts/detail/%s/info' + '/' +this.state.displayMode, deleteAction: this.deletePost},
count: posts.count
};
}else{
data = posts.items.length > 0 ? posts.items.map(key => {
key.name = key.author? `${key.author.firstName} ${key.author.lastName}`: '';
key.numberComment = key.comments ? key.comments.length: 0;
key.numberLike = key.likes ? key.likes.length : 0;
key.categoryName = key.category ? key.category.name : '';
key.createdDate = moment(key._created).format('MM/DD/YYYY');
return key;
}): []
listOptions = {
headers: [I18n.t('common.title'), I18n.t('post.category'), I18n.t('post.author'), I18n.t('post.created_date_time'), I18n.t('post.number_comment'), I18n.t('post.number_view'), I18n.t('post.number_like'), I18n.t('common.action')],
data: {
items: data,
mapping: ['content', 'categoryName','name', 'createdDate', 'numberComment', 'views', 'numberLike', 'action'],
align:["","","","","center","center","center",""],
render: [
{
key: "content",
render: (item) => {
return <div className="overflow" style={{ width: '180px'}}>{item.content}</div>
}
},
{
key: "categoryName",
render: (item) => {
return <div className="overflow" style={{ width: '140px'}}>{item.categoryName}</div>
}
},
{
key: "name",
render: (item) => {
return <div className="overflow" style={{ width: '60px'}}>{item.name}</div>
}
}
],
},
params: {url: '/posts/detail/%s/info' + '/' +this.state.displayMode, deleteAction: this.deletePost},
count: posts.count
};
}
return (
<div className="table-page">
<h4 className="module-title">{I18n.t('post.page.title')}</h4>
<PostFilter
categories={categories}
searchKey={this.state.searchKey}
fromDate={this.state.fromDate}
toDate={this.state.toDate}
onSearch={this.handleSearch}
onShow={this.handleShowFormNew}
onChangeDate = {this.handleChangeDate}
onChangeFilter = {this.handlelChangeFilter}
/>
<List {...listOptions} />
<PaginationView count={posts.count} currentPage={currentPage} onSelectPage={(page) => {actions.setCurrentPage(page)}}/>
</div>
);
}
}
function mapStateToProps(state, ownProps) {
return {
posts: state.posts.page,
categories: state.posts.categories,
paging: state.paging,
i18n: state.i18n,
triggerRefresh: state.posts.triggerRefresh
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(combineActions, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(PostPage);
postsReducer
/**
* Created by admin on 7/12/17.
*/
import {POSTS} from '../const/actionTypes';
const initialState = {
page: {
items: [],
count: 0
},
detail: {},
post: {
items: [],
count: 0
},
comment: {
items: [],
count: 0
},
triggerRefresh: false,
categories: [],
currentP: {},
pListComment: [],
pList: [],
pListReporter: [],
};
export default function posts(state = initialState, action) {
switch(action.type) {
case POSTS.FETCH_SUCCESS:
return {...state, page: {items: action.payload.items, count: action.payload.count}};
case POSTS.FETCH_CATEGORY_SUCCESS:
return {...state, categories: action.payload};
case POSTS.TRIGGER_REFRESH:
return {...state, triggerRefresh: !state.triggerRefresh}
case POSTS.GET_POST_DETAIL_SUCCESS:
return { ...state, currentP: Object.assign({}, action.payload) };
case POSTS.CREATE_SUCCESS:
return { ...state, pList: [action.payload, ...state.pList], currentP: {} };
case POSTS.UPDATE_SUCCESS:
let updated = action.payload;
let newItems = state.pList.map(p => {
return p._id === updated._id ? Object.assign({}, p, updated) : p;
});
return { ...state, pList: newItems, currentPS: action.payload };
case POSTS.DELETE_POSTS_SUCCESS:
return { ...state, pList: state.pList.filter(item => item._id != action.payload) };
case POSTS.GET_POST_COMMENT_SUCCESS:
return { ...state, pListComment: action.payload };
case POSTS.GET_POST_REPORTER_SUCCESS:
return { ...state, pListReporter: action.payload };
default:
return state;
}
}
Related
I have an issue with my React application (with Redux Saga), I'm getting the console error:
The service worker navigation preload request was cancelled before 'preloadResponse' settled. If you intend to use 'preloadResponse', use waitUntil() or respondWith() to wait for the promise to settle.
I see this error on the console only on Chrome, not in Firefox or Edge.
This error does not affect my application.
The following steps reproduce the error:
1. Main page upload.
2. Go to movie details page.
3. Go back to main page.
Main.jsx
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { mainActions } from '../../store/actions/actions';
import './Main.scss';
import { MoviesList, SearchPanel } from '../../components';
const propTypes = {};
const defaultProps = {};
class Main extends Component {
constructor(props) {
super(props);
this.handleSearchTextChange = this.handleSearchTextChange.bind(this);
this.handleLoadMoreButtonClick = this.handleLoadMoreButtonClick.bind(this);
this.handleMovieClick = this.handleMovieClick.bind(this);
this.handleFavoriteMovieClick = this.handleFavoriteMovieClick.bind(this);
}
componentDidMount() {
this.handleComponentDidMount();
}
handleComponentDidMount() {
const { moviesList } = this.props;
if (!moviesList || moviesList.length <= 0) {
this.getMovies(null, false);
}
}
handleLoadMoreButtonClick() {
this.getMovies(null, false);
}
handleMovieClick(e) {
if (e.target.className === 'movie') {
this.props.history.push(`/details/${e.currentTarget.dataset.id}`);
}
}
handleSearchTextChange(e) {
const { pageNumber, favoriteMoviesList } = this.props;
this.props.onSearchTextChange({
searchText: e.target.value,
pageNumber: pageNumber,
favoriteMoviesList: favoriteMoviesList
});
}
handleFavoriteMovieClick(e) {
const { id, name, posterId } = e.currentTarget.dataset;
const { moviesList, favoriteMoviesList } = this.props;
this.props.onUpdateFavoriteMovies({
updatedMovie: { id: id, name: name, posterId: posterId },
favoriteMoviesList: favoriteMoviesList,
moviesList: moviesList
});
}
getMovies(updatedSearchText, isSearchChange) {
const { searchText, pageNumber, favoriteMoviesList } = this.props;
this.props.onLoadMovies({
pageNumber: pageNumber,
favoriteMoviesList: favoriteMoviesList,
updatedSearchText: isSearchChange ? updatedSearchText : searchText,
isSearchChange: isSearchChange
});
}
render() {
const { searchText, isLoadingMoreMovies, isPager, moviesList } = this.props;
return (
<div className="main-area">
<SearchPanel
searchText={searchText}
onSearchTextChange={this.handleSearchTextChange}
/>
<MoviesList
pageName='movies'
moviesList={moviesList}
isLoadingMoreMovies={isLoadingMoreMovies}
isPager={isPager}
onLoadMoreClick={this.handleLoadMoreButtonClick}
onMovieClick={this.handleMovieClick}
onFavoriteMovieClick={this.handleFavoriteMovieClick}
/>
</div>
);
}
}
Main.propTypes = propTypes;
Main.defaultProps = defaultProps;
const mapStateToProps = (state) => {
return {
searchText: state.main.searchText,
pageNumber: state.main.pageNumber,
isLoadingMoreMovies: state.main.isLoadingMoreMovies,
isPager: state.main.isPager,
moviesList: state.main.moviesList,
favoriteMoviesList: state.main.favoriteMoviesList
};
};
const mapDispatchToProps = (dispatch) => {
return {
onLoadMovies: (request) => dispatch(mainActions.loadMovies(request)),
onSearchTextChange: (request) => dispatch(mainActions.searchTextChange(request)),
onUpdateFavoriteMovies: (request) => dispatch(mainActions.updateFavoriteMovies(request))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Main);
Details.jsx
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { detailsActions, mainActions } from '../../store/actions/actions';
import './Details.scss';
import { ActorsList, ButtonClick, CrewsList, FeaturesList, PageTitle, ProductionsList, Rating, Trailer } from '../../components';
import movieUtils from '../../utils/movie.utils';
const propTypes = {};
const defaultProps = {};
class Details extends Component {
constructor(props) {
super(props);
this.handleBackClick = this.handleBackClick.bind(this);
this.handleFavoriteMovieClick = this.handleFavoriteMovieClick.bind(this);
this.isFavorite = false;
}
componentDidMount() {
this.handleComponentDidMount();
}
handleComponentDidMount() {
if (this.props.moviesList.length <= 0) {
this.handleBackClick();
return;
}
const movieId = this.props.match.params.id;
if (!movieId) {
this.handleBackClick();
return;
}
this.props.onLoadMovieDetails(movieId);
this.updateIsFavorite(movieId);
}
numberWithCommas(number) {
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
updateIsFavorite(movieId) {
this.isFavorite = this.props.favoriteMoviesList.findIndex(movie => parseInt(movie.id) === parseInt(movieId)) > -1;
}
handleBackClick() {
this.props.history.push(`/`);
}
handleFavoriteMovieClick() {
const { movie, moviesList, favoriteMoviesList } = this.props;
this.props.onUpdateFavoriteMovies({
updatedMovie: { id: movie.id, name: movie.title, posterId: movie.poster_path },
favoriteMoviesList: favoriteMoviesList,
moviesList: moviesList
});
this.updateIsFavorite(movie.id);
}
render() {
const { movie, youtubeKey, credits } = this.props;
if (!movie) {
return null;
}
const { adult, poster_path, budget, genres, homepage, imdb_id, original_language, original_title,
overview, popularity, production_companies, production_countries, release_date, revenue, runtime, spoken_languages,
status, tagline, title, video, vote_average, vote_count } = movie;
const genresText = genres.map(genre => genre.name).join(', ');
const countriesText = production_countries.map(country => country.name).join(', ');
const languagesText = spoken_languages.map(language => language.name).join(', ');
const featuresList = [
{ item: 'Release Date', value: release_date },
{ item: 'Budget', value: `$${this.numberWithCommas(budget)}` },
{ item: 'Revenue', value: `$${this.numberWithCommas(revenue)}` },
{ item: 'Length', value: `${runtime} minutes` },
{ item: 'Popularity', value: popularity },
{ item: 'Original Title', value: original_title },
{ item: 'For Adults', value: adult ? 'Yes' : 'No' },
{ item: 'Original Language', value: original_language },
{ item: 'Spoken Languages', value: languagesText },
{ item: 'Countries', value: countriesText },
{ item: 'Status', value: status },
{ item: 'Is Video', value: video ? 'Yes' : 'No' }
];
const linksList = [];
if (homepage) {
linksList.push({ id: 1, name: 'Homepage', url: homepage });
}
if (imdb_id) {
linksList.push({ id: 2, name: 'IMDB', url: `https://www.imdb.com/title/${imdb_id}` });
}
const actorsList = movieUtils.removeDuplicates(credits ? credits.cast ? credits.cast : null : null, 'name');
const crewsList = movieUtils.removeDuplicates(credits ? credits.crew ? credits.crew : null : null, 'name');
return (
<div>
<section className="details-area">
<PageTitle
pageName='details'
pageTitle='Details'
/>
<ul className="details-content">
<li className="details-left" style={{ backgroundImage: `url('https://image.tmdb.org/t/p/original${poster_path}')` }}></li>
<li className="details-right">
<h2>{title} ({release_date.substr(0, 4)})</h2>
<p className="genres">{genresText}</p>
<p className="description short">{tagline}</p>
<Rating
rating={vote_average}
votesCount={this.numberWithCommas(vote_count)}
/>
<p className="description full">{overview}</p>
<div className="extra">
<FeaturesList
featuresList={featuresList.slice(0, 5)}
linksList={null}
isFavorite={this.isFavorite}
onFavoriteMovieClick={this.handleFavoriteMovieClick}
/>
{youtubeKey && <Trailer
youtubeKey={youtubeKey}
/>}
</div>
</li>
<div className="extra-features">
<FeaturesList
featuresList={featuresList.slice(5, featuresList.length)}
linksList={linksList}
isFavorite={null}
onFavoriteMovieClick={null}
/>
<ProductionsList
productionsList={production_companies}
/>
</div>
</ul>
</section>
<section className="actors-area">
<PageTitle
pageName='actors'
pageTitle='Cast'
/>
<ActorsList
actorsList={actorsList}
/>
</section>
<section className="crew-area">
<PageTitle
pageName='crew'
pageTitle='Crew'
/>
<CrewsList
crewsList={crewsList}
/>
</section>
<ButtonClick
buttonText={'Back'}
buttonTitle={'Back'}
isLoading={false}
onClick={this.handleBackClick}
/>
</div>
);
}
}
Details.propTypes = propTypes;
Details.defaultProps = defaultProps;
const mapStateToProps = (state) => {
return {
movie: state.details.movie,
youtubeKey: state.details.youtubeKey,
credits: state.details.credits,
moviesList: state.main.moviesList,
favoriteMoviesList: state.main.favoriteMoviesList
};
};
const mapDispatchToProps = (dispatch) => {
return {
onLoadMovieDetails: (movieId) => dispatch(detailsActions.loadDetails(movieId)),
onUpdateFavoriteMovies: (request) => dispatch(mainActions.updateFavoriteMovies(request))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Details);
What I already looked in:
Getting The service worker navigation preload request was cancelled before 'preloadResponse' settled
https://learn.microsoft.com/en-us/answers/questions/108004/getting-the-service-worker-navigation-preload-requ.html
https://support.google.com/mail/thread/4055804?hl=en
https://love2dev.com/pwa/service-worker-preload/
I tried to put this on Details.jsx page, but it didn't work:
self.addEventListener('fetch', event => {
event.respondWith(async function () {
// Respond from the cache if we can
const cachedResponse = await caches.match(event.request);
if (cachedResponse) return cachedResponse; // Else, use the preloaded response, if it's there
const response = await event.preloadResponse;
if (response) return response; // Else try the network.
return fetch(event.request);
}());
});
self.addEventListener('activate', event => {
event.waitUntil(async function () {
// Feature-detect
if (self.registration.navigationPreload) { // Enable navigation preloads!
console.log('Enable navigation preloads!');
await self.registration.navigationPreload.enable();
} return;
})();
});
How can I solve this issue? Thanks.
Had same error, even my iframe wasn't loading..whatever video you are using from youtube use nocookie/embed in url. It's working for me.
Try changing https://www.youtube.com/watch?v=i8eBBG46H8A to
https://www.youtube-nocookie.com/embed/i8eBBG46H8A
Hope nocookie & embed helps..!!
I am creating an activity, where a user needs to match two words on click. Like on the picture below.
If words match they should get disabled.
My state is following
this.state = {
data: [],
mixedWords: [],
myanswers: [],
allPairs: [],
checked: false,
isCorrect: false,
isIncorrect: false
};
For example myanswers array maybe like this.
["more than", "более"]
mixedWords array is the following
[{translation: "more than", disabled: false},
{translation: "capital", disabled: false},
{word: "более", disabled: false},
{translation: "famous", disabled: false},
{word: "проживает", disabled: false},
{translation: "is living", disabled: false},
{word: "известный", disabled: false},
{word: "столице", disabled: false}
]
This function is responsible for modifying disabled property. But the problem is that it outputs only filtered items. How can I output mixedWords array with modifyed disabled property for specific items
const myFunction = (value) => {
const mixedWords = [...this.state.mixedWords]
const result = mixedWords.filter(word => word.translation === value || word.word === value );
const newResult = Object.assign({}, result[0], { disabled:true })
this.setState({
mixedWords:[newResult]
})
}
this.state.myanswers.forEach(myFunction)
Full code
/* eslint-disable no-extend-native */
import React, { Component } from "react";
//import click from "../data/media/click.wav";
//import correct from "../data/media/correct.wav";
//import denied from "../data/media/denied.mp3";
let _ = require("lodash");
class Quiz extends Component {
constructor (props) {
super(props);
this.state = {
data: [],
mixedWords: [],
myanswers: [],
allPairs: [],
checked: false,
isCorrect: false,
isIncorrect: false
};
}
componentDidMount() {
let mixedWords = [];
let allPairs = [];
this.props.data.quiz && this.props.data.quiz.map((item) => {
mixedWords.push({word:item.word, disabled:false},{ translation:item.translation,disabled:false});
allPairs.push(item.pair);
return (mixedWords, allPairs);
});
this.setState({
data: this.props.data.quiz,
mixedWords: _.shuffle(mixedWords),
allPairs
});
//console.log(this.props.data);
}
selectWords = (e) => {
let items = e.target.value;
let myanswers = this.state.myanswers.concat(items);
this.setState({ myanswers }, () => {
if (this.state.myanswers.length === 2) {
if (this.checkAnswers(this.state.myanswers, this.state.allPairs)) {
console.log("correct");
const myFunction = (value) => {
const mixedWords = [...this.state.mixedWords]
const result = mixedWords.filter(word => word.translation === value || word.word === value );
const newResult = Object.assign({}, result[0], { disabled:true })
this.setState({
mixedWords:[newResult]
})
}
this.state.myanswers.forEach(myFunction)
this.setState({
myanswers:[]
})
} else {
console.log("incorrect");
this.setState({
myanswers:[]
})
}
} else {
console.log('choose a pair');
}
});
};
checkAnswers = (answersArr, allPairs) => {
let bools = []
allPairs.forEach((arr) => {
this.arraysEqual(answersArr, arr);
//console.log(this.arraysEqual(answersArr, arr));
//console.log(arr, this.state.myanswers);
bools.push(this.arraysEqual(answersArr, arr))
});
if (bools.includes(true)) {
return true
}
};
arraysEqual = (a, b) => {
return a.sort().toString() === b.sort().toString()
};
render() {
console.log(this.state.mixedWords);
console.log(this.state.myanswers);
//console.log(this.state.allPairs);
//console.log(this.state.myanswers.join(" ") === this.state.answers.join(" "));
return (
<div>
<div className="tags are-medium">
{ this.state.mixedWords.map((item) => (
<button disabled={item.disabled} value={ item.word || item.translation } onClick={ (e) => { this.selectWords(e); } } className="tag is-warning">{ item.word || item.translation }</button>
)) }
</div>
</div>
);
}
}
export default Quiz;
selectWords = (e) => {
let items = e.target.value;
let myanswers = this.state.myanswers.concat(items);
this.setState({ myanswers }, () => {
if (this.state.myanswers.length === 2) {
if (this.checkAnswers(this.state.myanswers, this.state.allPairs)) {
console.log("correct");
const myFunction = (value) => {
this.setState({
mixedWords:this.state.mixedWords.map(word => word.translation === value || word.word === value ? Object.assign({}, word, { disabled:true }) : word)
})
}
this.state.myanswers.forEach(myFunction)
this.setState({
myanswers:[]
})
} else {
console.log("incorrect");
this.setState({
myanswers:[]
})
}
} else {
console.log('choose a pair');
}
});
};
I cannot get my reducer to update. I can step into the action when I fire this.completeQuiz(id) in my debugger but my state doesn't get updated. Any ideas?
import {
submitAnswer,
resetQuiz,
nextQuestion,
completeQuiz
} from "../actions/videos";
class TestYourselfScreen extends React.Component {
constructor(props) {
super(props);
this.onCapture = this.onCapture.bind(this);
}
completeQuiz = id => {
let video = this.props.videos.find(obj => obj.id == id);
let correctAnswers = video.results.correctAnswers;
const questionsFiltered = video.questions.filter(obj => obj.question != "");
completeQuiz({
id,
totalScore: correctAnswers.length / questionsFiltered.length
});
};
render() {
.....
return (
{questionsFiltered.length > 0 && !completed && (
<View
style={{
flex: 1
}}
>
....
<Button
title={lastQuestion ? "Finish" : "Next"}
buttonStyle={[styles.button]}
disabled={
!results.correctAnswers.includes(current) &&
!results.incorrectAnswers.includes(current)
? true
: false
}
onPress={() =>
lastQuestion ? this.completeQuiz(id) : this.next(id, current)
}
/>
</View>
)}
{completed === true && (
<View
style={{
flex: 1
}}
>
<ViewShot ref="viewShot" options={{ format: "jpg", quality: 0.9 }}>
...
</View>
)}
</ScrollView>
);
}
}
const mapStateToProps = state => {
return {
videos: state.tcApp.videos
};
};
const mapDispatchToProps = dispatch => ({
submitAnswer: data => dispatch(submitAnswer(data)),
resetQuiz: id => dispatch(resetQuiz(id)),
nextQuestion: data => dispatch(nextQuestion(data)),
completeQuiz: data => dispatch(completeQuiz(data))
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(TestYourselfScreen);
Action:
export const completeQuiz = data => ({
type: "COMPLETE",
data
});
Reducer:
import { trimText } from "../helpers";
export function tcApp(
state = { videos: [], search: { videos: [], term: "" } },
action
) {
switch (action.type) {
....
case "COMPLETE": {
const { completed, totalScore, id } = action.data;
return {
videos: state.videos.map(video =>
video.id === id
? {
...video,
results: {
totalScore
},
completed: true
}
: video
),
search: { term: "", videos: [] }
};
}
default:
return state;
}
}
I think your action is available through props do it as this
completeQuiz = id => {
let video = this.props.videos.find(obj => obj.id == id);
let correctAnswers = video.results.correctAnswers;
const questionsFiltered = video.questions.filter(obj => obj.question != "");
this.props.completeQuiz({
id,
totalScore: correctAnswers.length / questionsFiltered.length
});
};
because we mapDispatchToProps
Hope it helps
I have a method to submit the edited form, but when I'm clicking submit button, nothing happens. Via the console I figured out, that eventIndex = -1. What should I fix in the code below?
editEvent(event) {
const { currentUser, editGoogleCalendarEvent, calendarEvents } = this.props;
const {
events } = this.state;
let onlyDate = false;
console.log('event', event);
console.log('calendarEvents', calendarEvents);
const idx = events.indexOf(event);
const eventIndex = _.findIndex(calendarEvents.details.items, { id: event.id });
const editedEvent = { ...event };
console.log('Event Index', eventIndex);
const nextEvents = [...events];
nextEvents.splice(idx, 1, editedEvent);
if (eventIndex !== -1) {
const item = calendarEvents.details.items[eventIndex];
if (item.start.date && item.end.date) {
editedEvent.start = moment(event.start).format('YYYY-MM-DD');
editedEvent.end = moment(event.end).format('YYYY-MM-DD');
onlyDate = true;
}
}
this.setState({
events: nextEvents,
}, () => {
console.log('Object', { id: event.event.id, title: event.formValues.title, userId: currentUser.id, timezone: currentUser.timezone, onlyDate });
editGoogleCalendarEvent({
id: event.event.id,
start: moment(event.event.start).hours(event.formValues.period === 'AM' ? event.formValues.hour % 12 : (event.formValues.hour % 12) + 12).minutes(event.formValues.minute).toISOString(),
end: moment(event.event.end).hours(event.formValues.period === 'AM' ? event.formValues.hour % 12 : (event.formValues.hour % 12) + 12).minutes(event.formValues.minute).toISOString(),
title: event.formValues.title,
userId: currentUser.id,
timezone: currentUser.timezone,
onlyDate,
});
});
}
Form:
<EditCalendarEventForm
show={this.state.editShow}
isSubmitting={editEventProcess.isSubmitting}
calendarEvent={this.state.calendarEvent}
onSubmit={this.editEvent}
onHide={this.hideEditEventModal}
/>
Here is the whole page, maybe you will understand the situation better with it. Also I have an EditFormPage and api to work with the requests.
I was using moveEvent as an example to create editEvent method.
import React, { PropTypes } from 'react';
import moment from 'moment-timezone';
import Helmet from 'react-helmet';
import _ from 'lodash';
import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';
import { GoogleLogin, GoogleLogout } from 'react-google-login';
import { reduxForm, reset } from 'redux-form';
import BigCalendar from 'react-big-calendar';
import withDragAndDrop from 'react-big-calendar/lib/addons/dragAndDrop';
import 'react-big-calendar/lib/less/styles.less';
import 'react-big-calendar/lib/addons/dragAndDrop/styles.less';
import AddCalendarEventForm from '../../../app/components/AddCalendarEventForm';
import EditCalendarEventForm from '../../../app/components/EditCalendarEventForm';
import { translate } from '../../../common/utilities/localization';
import {
selectCurrentUser,
selectCurrentGoogleUser,
} from '../../containers/App/selectors';
import {
submitGoogleAuth,
fetchGoogleCalendarEvents,
editGoogleCalendarEvent,
addGoogleCalendarEvent,
} from './actions';
import {
selectGoogleAuth,
selectCalendarEvents,
selectAddEventProcess,
selectEditEventProcess,
} from './selectors';
const formName = 'addCalendarEvent';
const formNameEdit = 'editCalendarEvent';
const DragAndDropCalendar = withDragAndDrop(BigCalendar);
const localizer = BigCalendar.momentLocalizer(moment);
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser(),
currentGoogleUser: selectCurrentGoogleUser(),
googleAuth: selectGoogleAuth(),
calendarEvents: selectCalendarEvents(),
addEventProcess: selectAddEventProcess(),
editEventProcess: selectEditEventProcess(),
});
const mapDispatchToProps = (dispatch) => ({
submitGoogleAuth: (externalUserId, googleToken) => dispatch(submitGoogleAuth(externalUserId, googleToken)),
fetchGoogleCalendarEvents: (data) => dispatch(fetchGoogleCalendarEvents(data)),
editGoogleCalendarEvent: (data) => dispatch(editGoogleCalendarEvent(data)),
addGoogleCalendarEvent: (data) => dispatch(addGoogleCalendarEvent(data)),
resetForm: () => dispatch(reset(formName)),
resetEditForm: () => dispatch(reset(formNameEdit)),
});
#reduxForm({
form: formName,
})
#connect(mapStateToProps, mapDispatchToProps)
export default class CalendarPage extends React.Component {
static propTypes = {
currentUser: PropTypes.any,
currentGoogleUser: PropTypes.any,
submitGoogleAuth: PropTypes.func.isRequired,
googleAuth: PropTypes.object,
fetchGoogleCalendarEvents: PropTypes.func,
calendarEvents: PropTypes.object,
editGoogleCalendarEvent: PropTypes.func,
addGoogleCalendarEvent: PropTypes.func,
addEventProcess: PropTypes.object,
editEventProcess: PropTypes.object,
resetForm: PropTypes.func,
resetEditForm: PropTypes.func,
};
constructor(props) {
super(props);
this.state = {
events: [],
show: null,
calendarEvent: null,
editShow: null,
};
this.onSuccess = this.onSuccess.bind(this);
this.onFailure = this.onFailure.bind(this);
this.moveEvent = this.moveEvent.bind(this);
this.editEvent = this.editEvent.bind(this);
this.newEvent = this.newEvent.bind(this);
this.showEventModal = this.showEventModal.bind(this);
this.showEditEventModal = this.showEditEventModal.bind(this);
this.hideEventModal = this.hideEventModal.bind(this);
this.hideEditEventModal = this.hideEditEventModal.bind(this);
}
componentDidMount() {
const { currentUser, currentGoogleUser } = this.props;
if (currentGoogleUser && currentGoogleUser.expires_at && moment(currentGoogleUser.expires_at).isAfter(moment())) {
this.props.fetchGoogleCalendarEvents({ ...currentGoogleUser, userId: currentUser.id });
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.currentGoogleUser !== this.props.currentGoogleUser) {
this.props.fetchGoogleCalendarEvents({ ...nextProps.currentGoogleUser, userId: nextProps.currentUser.id });
}
if (nextProps.calendarEvents && nextProps.calendarEvents.details) {
const events = [];
for (const item of nextProps.calendarEvents.details.items) {
if (item.start && item.end) {
events.push({
id: item.id,
title: item.summary,
start: moment(item.start.dateTime || item.start.date),
end: moment(item.end.dateTime || item.end.date),
});
}
}
this.setState({ events });
}
if (!nextProps.addEventProcess.isSubmitting && this.props.addEventProcess.isSubmitting) {
this.hideEventModal();
}
if (!nextProps.editEventProcess.isSubmitting && this.props.editEventProcess.isSubmitting) {
this.hideEventModal();
}
}
onSuccess(ev) {
const { submitGoogleAuth, currentUser } = this.props;
submitGoogleAuth(currentUser.id, { ...ev.tokenObj, profileEmail: ev.profileObj.email });
}
onFailure(ev) {
console.log('onFailure', ev);
}
moveEvent({ event, start, end, isAllDay: droppedOnAllDaySlot }) {
const { currentUser, editGoogleCalendarEvent, calendarEvents } = this.props;
const { events } = this.state;
let onlyDate = false;
const idx = events.indexOf(event);
const eventIndex = _.findIndex(calendarEvents.details.items, { id: event.id });
let allDay = event.allDay;
if (!event.allDay && droppedOnAllDaySlot) {
allDay = true;
} else if (event.allDay && !droppedOnAllDaySlot) {
allDay = false;
}
const updatedEvent = { ...event, start, end, allDay };
const nextEvents = [...events];
nextEvents.splice(idx, 1, updatedEvent);
if (eventIndex !== -1) {
const item = calendarEvents.details.items[eventIndex];
if (item.start.date && item.end.date) {
updatedEvent.start = moment(start).format('YYYY-MM-DD');
updatedEvent.end = moment(end).format('YYYY-MM-DD');
onlyDate = true;
}
}
this.setState({
events: nextEvents,
}, () => {
editGoogleCalendarEvent({ ...updatedEvent, userId: currentUser.id, timezone: currentUser.timezone, onlyDate });
});
}
editEvent(event) {
const { currentUser, editGoogleCalendarEvent, calendarEvents } = this.props;
const { events } = this.state;
let onlyDate = false;
console.log('event', event);
console.log('calendarEvents', calendarEvents);
const idx = events.indexOf(event);
const eventIndex = _.findIndex(calendarEvents.details.items, { id: event.id });
const editedEvent = { ...event };
console.log('Event Index', eventIndex);
const nextEvents = [...events];
nextEvents.splice(idx, 1, editedEvent);
if (eventIndex !== -1) {
const item = calendarEvents.details.items[eventIndex];
if (item.start.date && item.end.date) {
editedEvent.start = moment(event.start).format('YYYY-MM-DD');
editedEvent.end = moment(event.end).format('YYYY-MM-DD');
onlyDate = true;
}
}
this.setState({
events: nextEvents,
}, () => {
console.log('Object', { id: event.event.id, title: event.formValues.title, userId: currentUser.id, timezone: currentUser.timezone, onlyDate });
editGoogleCalendarEvent({
id: event.event.id,
start: moment(event.event.start).hours(event.formValues.period === 'AM' ? event.formValues.hour % 12 : (event.formValues.hour % 12) + 12).minutes(event.formValues.minute).toISOString(),
end: moment(event.event.end).hours(event.formValues.period === 'AM' ? event.formValues.hour % 12 : (event.formValues.hour % 12) + 12).minutes(event.formValues.minute).toISOString(),
title: event.formValues.title,
userId: currentUser.id,
timezone: currentUser.timezone,
onlyDate,
});
});
}
resizeEvent = ({ event, start, end }) => {
const { events } = this.state;
const nextEvents = events.map(existingEvent => {
return existingEvent.id === event.id
? { ...existingEvent, start, end }
: existingEvent;
});
this.setState({
events: nextEvents,
});
// console.log(`${event.title} was resized to ${start}-${end}`);
}
newEvent(params) {
const { currentUser, addGoogleCalendarEvent } = this.props;
const { event, formValues } = params;
const newEvent = {
title: formValues.title,
description: formValues.description ? formValues.description : null,
allDay: event.slots.length === 1,
start: moment(event.start).hours(formValues.period === 'AM' ? formValues.hour % 12 : (formValues.hour % 12) + 12).minutes(formValues.minute).toISOString(),
end: moment(event.end).hours(formValues.period === 'AM' ? formValues.hour % 12 : (formValues.hour % 12) + 12).minutes(formValues.minute).toISOString(),
};
this.setState({
calendarEvent: null,
}, () => {
addGoogleCalendarEvent({ ...newEvent, userId: currentUser.id, timezone: currentUser.timezone });
});
}
showEventModal(event) {
this.setState({ calendarEvent: event, show: true });
}
showEditEventModal(event) {
const { calendarEvents } = this.props;
const eventIndex = _.findIndex(calendarEvents.details.items, { id: event.id });
const item = calendarEvents.details.items[eventIndex];
this.setState({ calendarEvent: item, editShow: true });
}
hideEventModal() {
const { resetForm } = this.props;
this.setState({ show: false, calendarEvent: null }, () => {
resetForm();
});
}
hideEditEventModal() {
const { resetEditForm } = this.props;
this.setState({ editShow: false, calendarEvent: null }, () => {
resetEditForm();
});
}
render() {
const { currentGoogleUser, addEventProcess, editEventProcess } = this.props;
let authorized = false;
if (currentGoogleUser && currentGoogleUser.expires_at) {
authorized = moment(currentGoogleUser.expires_at).isAfter(moment());
}
return (
<div>
<div className="container-fluid">
<Helmet title={translate('portals.page.calendarPage.helmetTitle')} />
<section className="calendar-section">
<h2 className="main-heading">{translate('portals.page.calendarPage.pageTitle')}</h2>
{!authorized &&
<GoogleLogin
clientId={GOOGLE_CLIENT_ID}
scope="https://www.googleapis.com/auth/calendar"
className="google-login"
onSuccess={this.onSuccess}
onFailure={this.onFailure}
>
<i className="google-image" />
<span> Sign in with Google</span>
</GoogleLogin>
}
{authorized &&
<DragAndDropCalendar
selectable
events={this.state.events}
localizer={localizer}
onEventDrop={this.moveEvent}
resizable
onEventResize={this.resizeEvent}
onSelectSlot={this.showEventModal}
onSelectEvent={this.showEditEventModal}
defaultView={BigCalendar.Views.MONTH}
defaultDate={new Date()}
views={{ month: true }}
/>
}
<AddCalendarEventForm
show={this.state.show}
isSubmitting={addEventProcess.isSubmitting}
calendarEvent={this.state.calendarEvent}
onSubmit={this.newEvent}
onHide={this.hideEventModal}
/>
<EditCalendarEventForm
show={this.state.editShow}
isSubmitting={editEventProcess.isSubmitting}
calendarEvent={this.state.calendarEvent}
onSubmit={this.editEvent}
onHide={this.hideEditEventModal}
/>
</section>
</div>
</div>
);
}
}
const eventIndex = _.findIndex(calendarEvents.details.items, { id: event.id });
Apparently, there is an array which is called _, I can't see it anywhere in your code, you should change the way your are doing the findIndex() method.
suchlike calendarEvents.details.items.findIndex({id: event.id})
although, I don't think there is a way to find a prop value inside an object this way.
you may want to loop on instead.
So after looking over many different questions asking the about this warning, I have found that there is not one single reason why this would be occurring making it difficult to infer a solution on my own code.
So here is my code incase anyone has another pair of eyes they can put on it and spot maybe why i would be getting this error.
This error occurs when not on first arrival of the component but after leaving and returning to it again.
I have a smart container and a dumb component set up so here is the container:
import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { listOrders, listUseCases } from '../../actions/order';
import { storeWithExpiration } from '../../utils/common.js';
import OrdersIndex from './OrdersIndex';
export class OrdersIndexContainer extends React.Component {
static propTypes = {
account: PropTypes.object.isRequired,
orders: PropTypes.object.isRequired,
platformMap: PropTypes.object.isRequired,
progress: PropTypes.number,
listOrdersAction: PropTypes.func.isRequired,
listUseCasesAction: PropTypes.func.isRequired,
};
render() {
const { orders, platformMap, progress } = this.props;
return (
<div>
<OrdersIndex
orders={ orders }
platformMap={ platformMap }
progress={ progress }
/>
</div>
);
}
renderOrderIndex = () => {
}
componentWillMount = () => {
const { account, listOrdersAction, listUseCasesAction } = this.props;
const token = storeWithExpiration.get('token');
listOrdersAction(token);
listUseCasesAction(account.id, token);
}
}
function mapStateToProps(state) {
const { account, orderList, progress } = state;
const orders = orderList.get('orders');
const platformMap = orderList.get('platformMap');
return { account, platformMap, orders, progress };
}
export default connect(mapStateToProps, {
listOrdersAction: listOrders,
listUseCasesAction: listUseCases,
})(OrdersIndexContainer);
And here is the dumb component:
import React, { PropTypes } from 'react';
import { Link } from 'react-router';
import ReactDataGrid from 'react-data-grid';
import { Toolbar } from 'react-data-grid/addons';
import { Data } from 'react-data-grid/addons';
import moment from 'moment';
import { SIMPLE_DATE_FORMAT } from '../../config/app_config';
// import OrderWrapFormatter from './OrderWrapFormatter';
const TABLE_COLUMNS = [
{ key: 'cNumber', name: 'Customer #', width: 125 },
{ key: 'name', name: 'Name', width: 150 },
{ key: 'orderNumber', name: 'Order #', width: 90 },
{ key: 'platform', name: 'Platform' },
{ key: 'useCase', name: 'Use Case'/* , formatter: OrderWrapFormatter */ },
{ key: 'list', name: 'List' },
{ key: 'sku', name: 'SKU' },
{ key: 'startDate', name: 'Start Date' },
{ key: 'endDate', name: 'End Date' },
];
export default class OrdersIndex extends React.Component {
static propTypes = {
orders: PropTypes.object.isRequired,
platformMap: PropTypes.object.isRequired,
progress: PropTypes.number,
};
state = {
rows: [],
originalRows: [],
columns: TABLE_COLUMNS,
sortColumn: null,
sortDirection: null,
filters: {},
}
renderRows = (orders) => {
const _rows = [];
orders.map((o) => {
_rows.push({
key: o.order.id,
id: o.order.id,
cNumber: o.order.providerCustomerNumber,
name: o.order.company.name,
orderNumber: o.order.providerOrderNumber,
platform: o.platformUseCases[0].platform.description,
useCase: this.renderMulti(o.platformUseCases, 'useCase', 'description'),
list: this.renderMulti(o.listSKUs, 'dataSet', 'name'),
sku: this.renderMulti(o.listSKUs, 'fieldSet', 'name'),
startDate: moment(o.order.startDate).format(SIMPLE_DATE_FORMAT),
endDate: moment(o.order.endDate).format(SIMPLE_DATE_FORMAT),
});
return _rows;
});
return this.setState({
rows: _rows,
originalRows: _rows.slice(),
});
}
getRows = () => {
return Data.Selectors.getRows(this.state);
}
rowGetter = (rowIdx) => {
const rows = this.getRows();
return rows[rowIdx];
}
getSize = () => {
return this.getRows().length;
}
renderMulti = (multi, itemName, subItemName) => {
const objectArray = multi.map((object) => {
return object[itemName][subItemName];
});
return objectArray.join('\n');
}
handleGridSort = (sortColumn, sortDirection) => {
const { originalRows, rows } = this.state;
const comparer = (a, b) => {
if (sortDirection === 'ASC') {
return (a[sortColumn] > b[sortColumn]) ? 1 : -1;
}
else if (sortDirection === 'DESC') {
return (a[sortColumn] < b[sortColumn]) ? 1 : -1;
}
};
const newRows = sortDirection === 'NONE' ? originalRows.slice() : rows.sort(comparer);
this.setState({
rows: newRows,
});
}
handleRowUpdated = (e) => {
// merge updated row with current row and rerender by setting state
const { rows } = this.state;
Object.assign(rows[e.rowIdx], e.updated);
this.setState({
...rows,
});
}
handleFilterChange = (filter) => {
const { filters } = this.state;
const newFilters = Object.assign({}, filters);
if (filter.filterTerm) {
newFilters[filter.column.key] = filter;
}
else {
delete newFilters[filter.column.key];
}
this.setState({
filters: newFilters,
});
}
onClearFilters = () => {
// all filters removed
this.setState({
filters: {},
});
}
// Creates appropriate warnings to prevent entering
// the order form if the account is missing information
renderNotice = (message, buttonMessage, route) => {
return (
<div className="alert alert-warning">
<strong>Notice:</strong>
<p>{ message }</p>
<p>
<Link
to={ route }
className="btn btn-warning"
>
<i className='fa fa-plus'></i>
{ buttonMessage }
</Link>
</p>
</div>
);
}
render() {
const { platformMap, progress } = this.props;
const platformMessage = 'Your account is not associated with any platform use cases.' +
'You must select at least one use case before creating new orders.';
const platformButton = 'Add Use Cases';
const platformRoute = '/products';
return (
<div className="container">
<div className="row">
<div className="col-sm-12 col-md-8">
<h1>Orders</h1>
</div>
<div className="col-sm-12 col-md-4">
<span className="pull-right">
<Link
to="/orders/create/1"
className="btn btn-primary"
disabled
>
<i className='fa fa-plus'></i>Create New Order
</Link>
</span>
</div>
</div>
{ platformMap.size === 0 && progress === 0 ?
this.renderNotice(platformMessage, platformButton, platformRoute) : null }
<div className="row">
{ progress === 0 ?
<div className="col-md-12">
{ this.renderTable() }
</div> : null }
</div>
</div>
);
}
renderTable = () => {
const { orders } = this.props;
const { columns } = this.state;
return (
<div>
{ orders.size === 0 || orders === undefined ?
<p>Your account has no orders</p> :
<ReactDataGrid
onGridSort={ this.handleGridSort }
rowKey="key"
id="key"
columns={ columns }
rowGetter={ this.rowGetter }
rowsCount={ this.getSize() }
onRowUpdated={ this.handleRowUpdated }
toolbar={ <Toolbar enableFilter /> }
onAddFilter={ this.handleFilterChange }
onClearFilters={ this.onClearFilters }
minHeight={ 500 }
filterRowsButtonText="Search By Field"
/>
}
</div>
);
}
componentWillMount = () => {
const { orders } = this.props;
const columnArray =
TABLE_COLUMNS.map((c) => {
const copy = Object.assign({}, c);
copy.filterable = true;
copy.locked = true;
if (copy.key !== 'useCase') {
copy.sortable = true;
}
return copy;
});
this.setState({
columns: columnArray,
});
this.renderRows(orders);
}
componentWillReceiveProps = (nextProps) => {
const { orders } = nextProps;
if (orders.size > 0) {
this.renderRows(orders);
}
}
}
I understand this might be a lot but I cannot for the life of me determine what could be the cause. Thanks to anyone who takes a look.