简体   繁体   中英

Only last function create effect when calling same function at a time with different parameter in react useEffect

I have created a component called "CommonStyleGenerator", to generate simple style object with keys like height, width and bgColor. I have created a text fields in component and whenever text change in any of text field I am calling onStyleChange with changed field key and it's value to store changed value in parent component.

Here is the CommonStyleGenerator.js component code:

import React, { useEffect, useState } from 'react';
import { View, Text, TextInput, StyleSheet } from 'react-native';

const CommonStyleGenerator = ({ style = {
  height: "100%",
  width: "100%",
  bgColor: "#ffffff"
}, onStyleChange }) => {

  useEffect(() => {
    onStyleChange("height", "100%");
    onStyleChange("width", "100%");
    onStyleChange("bgColor", "#ffffff"); //Only this getting effect.
  }, []);
  
  return (
    <View>
      <TextInput 
        value={style?.height}
        placeholder="height"
        onChangeText={(text) => onStyleChange("height", text)}
        style={styles.textField}
      />
      <TextInput 
        value={style?.width}
        placeholder="width"
        onChangeText={(text) => onStyleChange("width", text)}
        style={styles.textField}
      />
      <TextInput 
        value={style?.bgColor}
        placeholder="background color"
        onChangeText={(text) => onStyleChange("bgColor", text)}
        style={styles.textField}
      />
    </View>
  )
}

const styles = StyleSheet.create({
  textField: {
    borderWidth: 1,
    marginVertical: 10
  }
})

export default CommonStyleGenerator;

And here is the code of how I called the component in my App.js :

import React, { useEffect, useState } from 'react';
import { View, Button, Text } from 'react-native';
import CommonStyleGenerator from './components/CommonStyleGenerator';

const App = () => {
  const [commonStyle, setCommonStyle] = useState(null);
  return (
    <View style={{flex: 1, alignItems: 'center', padding: 20}}>
      <CommonStyleGenerator 
        style={commonStyle}
        onStyleChange={(key, value) => setCommonStyle({
          ...commonStyle,
          [key]: value
        })}
      />
      <Text>{JSON.stringify(commonStyle, null, 2)}</Text>
    </View>
  )
}

export default App;

Now, what I want is that on load CommonStyleGenerator component, generate default style if user don't change any textfield. So I called onStyleChange function on useEffect for each key. But for only last key(bgColor) function is called.

Is anyone know how I can solve this issue?

snack.expo.io link

The commonStyle in state when the three initial onStyleChange s are called is null. Each time it's called, the new state is set with an object with a single key. The synchronous call of an onStyleChange after a previous onStyleChange hasn't updated the commonStyle variable outside yet.

Your current code is like doing:

onStyleChange({ height: '100%' });
onStyleChange({ width: '100%' });
onStyleChange({ bgColor: '#ffffff' });

so only the last object passed appears to be in state on the next render.

Use a callback instead, when setting:

    onStyleChange={(key, value) => setCommonStyle(commonStyle => ({
      ...commonStyle,
      [key]: value
    }))}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM