How to find unused style definitions in React? - css

Is there a way to automagically find unused style definitions in a React based project, like in this example?
Before:
const styles = StyleSheet.create({
name: {
color: '#e5e5e5'
}
});
const Hello = React.createClass({
render: function() {
return <Text style={styles.name}>Hello {this.props.name}</Text>;
}
});
After:
Developer has changed styles and "name" is not required any more. How can this kind of dead style code be automatically found?
const styles = StyleSheet.create({
name: { // Redundant now!
color: '#e5e5e5'
},
foo: {
color: '#e2e3b5'
}
});
const Hello = React.createClass({
render: function() {
return <Text style={styles.foo}>Hello {this.props.name}</Text>;
}
});

Possible solution
1) helpers.js
// helpers.js
import ReactTestUtils from 'react-addons-test-utils'
export function unusedStyles(component, styles) {
const renderer = ReactTestUtils.createRenderer();
renderer.render(component);
const rendered = renderer.getRenderOutput();
const myStylesInUse = stylesInUse(rendered);
return filterStyles(styles, myStylesInUse);
}
function stylesInUse(el) {
var arr = [];
function go(el) {
const { children, style } = el.props;
const childrenType = Object.prototype.toString.call(children);
style && arr.push(style)
if(childrenType === '[object Object]') {
go(children);
} else if(childrenType === '[object Array]') {
children.forEach(child => { go(child) });
}
}
go(el);
return arr;
}
function filterStyles(styles, compStyles) {
const arr = [];
for(let key in styles) {
const found = compStyles.find(item => item === styles[key]);
if(!found) arr.push(key)
}
return arr;
}
2) Component.js
import { unusedStyles } from './helpers';
const styles = StyleSheet.create({
one: {
color: 'one'
},
two: {
color: 'two'
},
three: {
color: 'three'
}
});
class Hello extends Component {
render() {
return (
<div style={styles.one}>
<div style={style.two}>Hello!</div>
</div>
)
}
}
// here you can test your styles
const myUnusedStyles = unusedStyles(<Hello />, styles)
// => ['three']
if(myUnusedStyles.length) {
console.log('UNUSED STYLES DETECTED', myUnusedStyles);
}
export default Hello

Related

How to access the div element with a key in React JS? (react-dnd)

This is a small app created using react-beautiful-dnd. I want to add individual css element for different key values passed through this div element. However I am unable to access this specific div element for the specific key value in css.
<div key={key} className={"column"}>
<ProjectWrapper className="border">
<hr className="hr"></hr>
<h3 className="title">{data.title}</h3>
</ProjectWrapper>
The entire source code:
import React, {useState} from 'react';
import './App.css';
import {DragDropContext, Droppable, Draggable} from "react-beautiful-dnd";
import _ from "lodash";
import {v4} from "uuid";
const item = {
id: v4(),
name: "Clean the house"
}
const item2 = {
id: v4(),
name: "Wash the car"
}
function App() {
const [text, setText] = useState("")
const [state, setState] = useState({
//creating 3 columns
"todo": {
title: "Todo",
items: [item, item2]//temporary data valuesa
},
"in-progress": {
title: "In Progress",
items: []
},
"done": {
title: "Completed",
items: []
}
})
const handleDragEnd = ({destination, source}) => {
if (!destination) {
return
}
if (destination.index === source.index && destination.droppableId === source.droppableId) {
return
}
// Creating a copy of item before removing it from state
const itemCopy = {...state[source.droppableId].items[source.index]}
setState(prev => {
prev = {...prev}
// Remove from previous items array
prev[source.droppableId].items.splice(source.index, 1)
// Adding to new items array location
prev[destination.droppableId].items.splice(destination.index, 0, itemCopy)
return prev
})
}
const addItem = () => {
setState(prev => {
return {
...prev,
todo: {
title: "Todo",
items: [
{
id: v4(),
name: text
},
...prev.todo.items
]
}
}
})
setText("")
}
//the dragdropcontext is the wrapper for draging elements
//dropable is the certain area inside the column where u can drop items
//dragble are the items in the column to be dragged
//here {_.map(state, (data, key) => {
//the above function is used to return the data and key of all 3 elements mentioned under use state() above
//the key: returns todo,inprogress,and done
//where as the data returns all the values of the variables within each key
return (
<div className="App">
<div>
<input type="text" value={text} onChange={(e) => setText(e.target.value)}/>
<button onClick={addItem}>Add</button>
</div>
<DragDropContext onDragEnd={handleDragEnd}>
{_.map(state, (data, key) => {
return(
<div key={key} className={"column"}>
<h3>{data.title}</h3>
<Droppable droppableId={key}>
{(provided, snapshot) => {
return(
<div
ref={provided.innerRef}
{...provided.droppableProps}
key = {"Todo"}
className={"droppable-col"}
>
{data.items.map((el, index) => {
return(
<Draggable key={el.id} index={index} draggableId={el.id}>
{(provided, snapshot) => {
console.log(snapshot)
return(
<div
className={`item ${snapshot.isDragging && "dragging"}`}
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
{el.name}
</div>
)
}}
</Draggable>
)
})}
{provided.placeholder}
</div>
)
}}
</Droppable>
</div>
)
})}
</DragDropContext>
</div>
);
}
export default App;
May I suggest using a utility like clsx
It will apply the specific class based on your value like so:
import clsx from 'clsx';
export default function App() {
const key = 'todo'; // or 'in-progress' or 'done'
return (
<div className={clsx('existingClass', key)}>
.
.
.
</div>
);
}
Which renders as <div class="existingClass todo">...</div>. You can configure your CSS classnames for the dynamic values. (in this case, todo)
// https://github.com/lukeed/clsx/blob/master/src/index.js
// MIT © Luke Edwards
function toVal(mix) {
var k, y, str='';
if (typeof mix === 'string' || typeof mix === 'number') {
str += mix;
} else if (typeof mix === 'object') {
if (Array.isArray(mix)) {
for (k=0; k < mix.length; k++) {
if (mix[k]) {
if (y = toVal(mix[k])) {
str && (str += ' ');
str += y;
}
}
}
} else {
for (k in mix) {
if (mix[k]) {
str && (str += ' ');
str += k;
}
}
}
}
return str;
}
function clsx() {
var i=0, tmp, x, str='';
while (i < arguments.length) {
if (tmp = arguments[i++]) {
if (x = toVal(tmp)) {
str && (str += ' ');
str += x
}
}
}
return str;
}
// https://github.com/lukeed/clsx/blob/master/src/index.js
// MIT © Luke Edwards
//-------------------
function App() {
const key = ['todo', 'in-progress', 'done'];
return (
<div className="App">
{key.map((k) => (
<span className={clsx('text', k)}>{k} - </span>
))}
</div>
);
}
ReactDOM.render(<App />, document.getElementById("react"));
.App {
font-family: sans-serif;
text-align: center;
}
.text{
font-size: 16px;
margin: 12px;
}
.todo {
color: orange;
}
.in-progress {
color: magenta;
}
.done {
color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>

I want to remove a className after a few seconds, or re trigger the class animation when condition is met

Goal: When there is a price change,i want the price number to higlight for a few seconds with a color. I do that with the toogleClassName.
Problem: When the iteration is UP UP,or DOWN DOWN,the element already has that class and the CSS animation already ran.
JSX Code:
import React, { useEffect, useState, useRef } from "react";
import styles from "./CoinContainer.module.css";
function usePrevious(data) {
const ref = useRef();
useEffect(() => {
ref.current = data;
}, [data]);
return ref.current;
}
export default function CoinContainer({ coin, price }) {
const [priceUpdated, setPrice] = useState("");
const prevPrice = usePrevious(priceUpdated);
// Update price
useEffect(() => {
setInterval(priceUpdate, 20000);
}, []);
// Apply different flash-color style according to up$ or down$ from prev
const toggleClassName = () => {
return prevPrice > priceUpdated ? styles.redPrice : styles.greenPrice;
};
function priceUpdate() {
return fetch(
`https://api.coingecko.com/api/v3/simple/price?ids=${coin}&vs_currencies=usd`
)
.then((data) => data.json())
.then((result) => {
let key = Object.keys(result);
setPrice(result[key].usd);
});
}
return (
<div className={styles.padding}>
<h2>{coin}</h2>
{/* Here is the problem,i would like to remove the class after a few seconds,or edit the CSS code to retrigger the animation */}
<h3 className={toggleClassName()}>
{priceUpdated ? priceUpdated : price}$
</h3>
</div>
);
}
CSS Code
#keyframes upFadeBetween {
from {
color: green;
}
to {
color: white;
}
}
#keyframes downFadeBetween {
from {
color: red;
}
to {
color: white;
}
}
.redPrice {
animation: downFadeBetween 5s;
color: white;
}
.greenPrice {
animation: upFadeBetween 5s;
color: white;
}
Thanks so much for any feedback/help!
You could use another variable called e.g. reset
const [reset, setReset] = useState(false);
And then set this value at your methods using setTimeout
const toggleClassName = () => {
setTimeout(() => setReset(true), 6000);
return prevPrice > priceUpdated ? styles.redPrice : styles.greenPrice;
};
function priceUpdate() {
return fetch(
`https://api.coingecko.com/api/v3/simple/price?ids=${coin}&vs_currencies=usd`
)
.then((data) => data.json())
.then((result) => {
let key = Object.keys(result);
setReset(false);
setPrice(result[key].usd);
});
}
and finally
<h3 className={reset ? "" : toggleClassName()}>
you can do this
handleClick = event => event.target.classList.add('click-state');
or as react is js library so definitly it will support js DOM elements, well there is no doubt that it uses DOM also.
so you can do this also,
for adding class
document.getElementById("id here").classList.add("classname here");
for removing class
document.getElementById("id here").classList.remove("classname here");
OR
you can also use react States
You can use a variable that will be updated every time you trigger the fetch.
In this case, we will call it animationStyle
function CoinContainer({ coin, price }) {
const [priceUpdated, setPrice] = useState("")
const [animationStyle, setAnimationStyle] = useState("")
useEffect(() => {
setInterval(priceUpdate, 20000)
}, [])
function updateAnimationStyle(){
if (prevPrice > priceUpdated) {
setAnimationStyle("redPrice")
} else {
setAnimationStyle("greenPrice")
}
setTimeout(() => {
setAnimation("")
}, 5000)
}
function priceUpdate() {
return fetch(
`https://api.coingecko.com/api/v3/simple/price?ids=${coin}&vs_currencies=usd`
)
.then((data) => data.json())
.then((result) => {
let key = Object.keys(result)
setPrice(result[key].usd)
updateAnimationStyle()
})
}
return (
<div className={styles.padding}>
<h2>{coin}</h2>
<h3 className={animationStyle}>//you avoid doing the conditional rendering that might be a bit confusing
{priceUpdated ? priceUpdated : price}$
</h3>
</div>
)
}
Okay, so basically, the approach is to avoid too large conditional rendering inside the jsx.
the function updateAnimationStyle gets called every time the fetch is triggered.
depending on the condition, updateAnimationStyle will set redPrice or greenPrice animations to animationStyle.
the animationStyle will clean after 5 seconds through setTimeout function. "it can not be less than 5s because you have set the animation duration to 5s".
const [priceUpdated, setPrice] = useState("") it is better to avoid this type of naming for variables.
Instead, if you use const [priceUpdated, setPriceUpdated] = useState(""), it will be more readable.
Hope it works for you!
Regards.

Calling a function from another component with redux

Trying to toggle open a modal from another component with redux. Almost there but not really sure how to finish it up - been looking around for a clear answer!
On the HomeScreen component (the main component), to activate the openModal method on the AddCircleModal component, causing the Modal to open.
The Modal - AddCircleModal: Using redux, I can successfully close the modal if I open it manually in the code
class AddCircleModal extends React.Component {
state = {
top: new Animated.Value(screenHeight),
modalVisible: false
}
// componentDidMount() {
// this.openModal()
// }
openModal = () => {
Animated.spring(this.state.top, {
toValue: 174
}).start()
this.setState({modalVisible: true})
}
closeModal = () => {
Animated.spring(this.state.top, {
toValue: screenHeight
}).start()
this.setState({modalVisible: false})
}
render() {
return (
<Modal
transparent={true}
visible={this.state.modalVisible}
>
<AnimatedContainer style={{ top: this.state.top, }}>
<Header />
<TouchableOpacity
onPress={this.closeModal}
style={{ position: "absolute", top: 120, left: "50%", marginLeft: -22, zIndex: 1 }}
>
<CloseView style={{ elevation: 10 }}>
<FeatherIcon name="plus" size={24} />
</CloseView>
</TouchableOpacity>
<Body />
</AnimatedContainer>
</Modal>
)
}
}
function mapStateToProps(state) {
return { action: state.action }
}
function mapDispatchToProps(dispatch) {
return {
closeModal: () =>
dispatch({
type: "CLOSE_MODAL"
})
}
}
export default connect(mapStateToProps, mapDispatchToProps)(AddCircleModal)
HomeScreen: The other component that I want to toggle from
//redux
import { connect } from 'react-redux'
import styles from './Styles'
class HomeScreen extends React.Component {
constructor() {
super();
this.state = {
};
}
toggleOpenCircleModal = () => {
// this.openModal() - what do I do with this to call the openModal function in the modal component?
console.log('owwwww weeeee')
}
render() {
return (
<SafeAreaView>
<HomeHeader openModal={this.toggleOpenCircleModal}/> - this method is because I'm calling toggleOpenCircleModal from a button in the header of the home screen. It works as it outputs the 'owwwww weeeee' string to the console.
<SafeAreaView style={{ width: '100%', flex: 1}} />
<AddCircleModal />
</SafeAreaView>
);
}
}
function mapStateToProps(state) {
return { action: state.action }
}
function mapDispatchToProps(dispatch) {
return {
openModal: () =>
dispatch({
type: "OPEN_MODAL"
})
}
}
export default connect(mapStateToProps, mapDispatchToProps)(HomeScreen)
modalToggle: The reducer
const initialState = {
action: ""
}
const modalToggle = (state = initialState, action) => {
switch (action.type) {
case "OPEN_MODAL":
return { ...state, action: "openModal" }
case "CLOSE_MODAL":
return { ...state, action: "closeModal" }
default:
return state
}
}
export default modalToggle
Right now, your components are not using redux store properly.
When you use mapStateToProps, you can access every redux store reducer. You can access every prop in them and these will be sent via props in your connected component. For instance:
//redux
import { connect } from 'react-redux'
import styles from './Styles'
class HomeScreen extends React.Component {
constructor() {
super();
this.state = {
};
}
toggleOpenCircleModal = () => {
if(this.props.action === 'openModal') {
this.props.openModal();
} else {
this.props.closeModal();
}
}
render() {
const { action } = this.props; // this.props.action is coming from Redux Store
return (
<SafeAreaView>
{action} // this will be 'openModal'
</SafeAreaView>
);
}
}
function mapStateToProps(state) {
return { action: state.action } // this will be available in HomeScreen as props.action
}
function mapDispatchToProps(dispatch) {
return {
openModal: () =>
dispatch({
type: "OPEN_MODAL"
})
}
}
export default connect(mapStateToProps, mapDispatchToProps)(HomeScreen)
You can read more on https://react-redux.js.org/using-react-redux/connect-mapstate.
The same goes for mapDispatchToProps. In your case, openModal will be available in props.openModal in your HomeScreen component. You can read more on https://react-redux.js.org/using-react-redux/connect-mapdispatch
Based on this, in your AddCircleModal component, you should be using props.action to evaluate if the modal should be visible. (props.action === 'openModal').
If you want to open or close your modal, you'll just need to call the openModal or closeModal dispatch call in your component. In HomeScreen component, in your function toggleOpenCircleModal, you will call openModal() or closeModal() depending on props.action === 'openModal'.
Lastly, you should be using just a boolean value to check for the modal visibility, instead of a string, if that's the only purpose for your reducer.
const initialState = false;
const modalToggle = (state = initialState, action) => {
switch (action.type) {
case "OPEN_MODAL":
return true;
case "CLOSE_MODAL":
return false;
default:
return state
}
}
export default modalToggle

React Navigation Preventing Going back to loading screen, reset not working

I have a React Native application which I have implemented. Currently the app opens up on a loading screen which after mounting checks the firebase.auth().onAuthStateChanged(...) feature.
The app basically decides whether or not to got to the login screen or to main screen depending on whether or not the user is already authenticated.
It is implemented like this:
Main Navigator:
const MainNavigator = TabNavigator({
auth: {
screen: TabNavigator({
login: { screen: LoginScreen },
signup: { screen: SignupScreen }
}, {
initialRouteName: 'login',
tabBarPosition: 'top',
lazy: true,
animationEnabled: true,
swipeEnabled: true,
tabBarOptions: {
labelStyle: { fontSize: 12 },
showIcon: true,
iconStyle: { width: 30, height: 30 }
}
})
},
main: {
screen: StackNavigator({
notes: { screen: NotesScreen }
}, {
initialRouteName: 'notes'
})
},
loading: { screen: LoadingScreen }
}, {
initialRouteName: 'loading',
lazy: true,
swipeEnabled: false,
animationEnabled: false,
navigationOptions: {
tabBarVisible: false
}
});
Loading Screen:
class LoadingScreen extends Component {
componentDidMount() {
const { navigate } = this.props.navigation;
firebase.auth().onAuthStateChanged(user => {
if (user) {
navigate('main');
} else {
navigate('auth');
}
});
}
render() {
return (
<View style={styles.spinnerStyle}>
<Spinner size="large" />
</View>
);
}
}
const styles = {
spinnerStyle: {
flexDirection: 'row',
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
};
This works well except for one issue.
When I press the hardware back button for Android, it goes to the application loading screen which obvious is undesired. How do I prevent that?
EDIT:
I've tried the following and it didn't work either:
const resetAction = (routeName) => NavigationActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName })],
key: null
});
class LoadingScreen extends Component {
componentDidMount() {
const { dispatch } = this.props.navigation;
firebase.auth().onAuthStateChanged(user => {
if (user) {
this.props.setUser(user);
dispatch(resetAction('main'));
} else {
dispatch(resetAction('auth'));
}
});
}
render() {
return (
<View style={styles.spinnerStyle}>
<Spinner size="large" />
</View>
);
}
}
use a switch navigator until the user logs in(loading and login page ) successsfully after that use a stack navigator(user homepage and otherpages which follow).
switchNavigator(loading, login, stackNavigator)
stackNavigator(user homepage,....)
Try a custom navigation component with custom back button support. Dont forget to add the reducer to yoru combine reducers function.
Create a navigation component:
import React, { Component } from 'react';
import { BackHandler } from 'react-native';
import { connect } from 'react-redux';
import { addNavigationHelpers } from 'react-navigation';
import MainNavigator from './MainNavigator';
class AppWithNavigationState extends Component {
componentDidMount () {
BackHandler.addEventListener('hardwareBackPress', () => {
this.props.dispatch({
type: 'Navigation/BACK'
});
return true;
});
}
componentWillUnmount () {
BackHandler.removeEventListener('hardwareBackPress');
}
render () {
return (
<MainNavigator navigation={addNavigationHelpers({
dispatch: this.props.dispatch,
state: this.props.nav
})}/>
);
}
}
export default connect((state) => ({ nav: state.nav }))(AppWithNavigationState);
Create a navigation reducer:
import { NavigationActions } from 'react-navigation';
import MainNavigator from './MainNavigator';
import { NAVIGATION_ON_SIGN_IN } from '../redux/actions/ActionTypes';
import { BackHandler } from 'react-native';
const initialState = MainNavigator.router.getStateForAction(MainNavigator.router.getActionForPathAndParams('loading'));
function appShouldClose (nextState) {
const { index, routes } = nextState;
return index === 0 || routes[1].routeName === 'auth';
}
export default (state = initialState, action) => {
const { router } = MainNavigator;
let nextState;
switch (action.type) {
case NavigationActions.BACK:
nextState = router.getStateForAction(action, state);
appShouldClose(nextState) && BackHandler.exitApp();
break;
default:
nextState = router.getStateForAction(action, state);
}
return nextState || state;
};
it is my solution :)
I have StageArea page. it is bridge between from login to timeline . User is not login then go to LoginPage. User is login then go to Timeline. User press back button then again go to TimeLine page not go to login page .( Sory for my english)
import React, { Component } from 'react';
import { View } from 'react-native';
import LoginForm from './LoginForm';
import Timeline from './Timeline';
import firebase from 'firebase';
import InitialPage from './InitialPage'
class StageArea extends Component {
state = {isLoggin:''};
componentWillMount(){
firebase.auth().onAuthStateChanged((user) => {
if (user) {
this.setState({ isLoggin:true})
}else {
this.setState({ isLoggin:false})
}
})
}
render() {
if(this.state.isLoggin)
{
return(<Timeline/>);
}
else if (this.state.isLoggin===false) {
return(<LoginForm/>);
}
}
}
export default StageArea;
Write the code below ,
static navigationOptions = {
header:null
};
Just before
render() {
return (
on the NotesScreen,There will not be any back button.

Dynamic Children Injection and Redux Binding

We are trying to inject dynamic children into a react app that is using React-Redux and Redux, and are experiencing an issue with the binding on the children props. I've distilled the problem into the following example code (JSFiddle). The issue is that the original rendered element updates just fine, but the dynamically injected portion does not. The strange thing is that the update is picked up in the redux store, and is fed to the props correctly.
const initialState = {
renderProperty: "Red Fish",
getChildrenProperty: "Blue Fish",
}
function MainReducer(state = initialState, action) {
switch (action.type) {
case 'PROBLEM_CHILD_INSIDE_RENDER':
return Object.assign({}, state, {
renderProperty: action.mutatedProperty
})
case 'PROBLEM_CHILD_INSIDE_GET_CHILDREN':
return Object.assign({}, state, {
getChildrenProperty: action.mutatedProperty
})
default:
return state
}
}
const store = Redux.createStore(MainReducer);
function mapStateToProps(state) {
return {
renderProperty : state.renderProperty,
getChildrenProperty : state.getChildrenProperty
}
}
function mapDispatchToProps(dispatch) {
return {
actions: Redux.bindActionCreators(actionCreators, dispatch)
};
}
class ProblemChild extends React.Component {
constructor() {
super();
this.childrenInjected = false;
this.state = {children: null};
}
/**
* Add children in setDynamicChildren() versus within render()
*/
componentDidMount() {
this.setDynamicChildren();
}
setDynamicChildren() {
this.setState({
children: this.getChildren()
});
}
getChildren() {
var me = this;
console.log(this);
return (
<div>
<br/>
<button style={{marginBottom: '10px'}}
onClick={me._handleGetChildrenAction.bind(me)} >UI State Change Action for prop in getChildren()</button>
<br/>
<span>prop in getChildren(): <b>{me.props.getChildrenProperty}</b></span>
</div>
)
}
render() {
var me = this,
childrenInjected = me.childrenInjected;
console.log(this.props);
if(me.state.children && !me.childrenInjected) {
return (
<div >
<button style={{marginBottom: '10px'}}
onClick={me._handleRenderAction.bind(me)} > UI State Change Action for prop in render()</button>
<br/>
<span>prop in render(): <b>{me.props.renderProperty}</b></span>
<br/>
{this.state.children} <br/>
</div>
)
}
else {
return (
<div>placeholder, yo</div>
)
}
}
_handleRenderAction() {
var me = this;
store.dispatch(actionForPropInsideRender('One Fish!'));
}
_handleGetChildrenAction() {
var me = this;
store.dispatch(actionForPropInsideGetChildren('Two Fish!'));
}
}
ProblemChild = ReactRedux.connect(mapStateToProps,mapDispatchToProps)(ProblemChild);
function actionForPropInsideRender(mutatedProperty) {
return {
type: 'PROBLEM_CHILD_INSIDE_RENDER',
mutatedProperty
}
}
function actionForPropInsideGetChildren(mutatedProperty) {
return {
type: 'PROBLEM_CHILD_INSIDE_GET_CHILDREN',
mutatedProperty
}
}
const actionCreators = {actionCreatorForPropInsideRender, actionCreatorForPropInsideGetChildren};
function actionCreatorForPropInsideRender(state, mutatedProperty) {
let newState = state.setIn(['uiState', 'renderProperty'], mutatedProperty),
nodeValue;
nodeValue = newState.getIn(['uiState', 'renderProperty']);
return newState;
}
function actionCreatorForPropInsideGetChildren(state, mutatedProperty) {
let newState = state.setIn(['uiState', 'getChildrenProperty'], mutatedProperty),
nodeValue;
nodeValue = newState.getIn(['uiState', 'getChildrenProperty']);
return newState;
}
ReactDOM.render(
<div>
<ReactRedux.Provider store={store}>
<ProblemChild />
</ReactRedux.Provider>
</div>,
document.getElementById('container')
);
setDynamicChildren() {
this.setState({
children: this.getChildren()
});
}
Is there a reason your intermixing redux state and local class state changes? From my experience this is asking for weird behaviour. I would swap this.setState for this.props.dispatch(action...) to update the redux store state. Do you still have issues when the complete state is now in redux? Otherwise a snapshot of redux dev tools state changes would be helpful in these cases.

Resources