Home > Mobile >  How can I concatenate a value on the second character of an array using useState();
How can I concatenate a value on the second character of an array using useState();

Time:09-28

I'm working on a React native project, and I'm using the useState hook and the TextInput property to store the user's input, I associate these inputs to a text component so that they are rendered and displayed every time the user types a number.

const BMIcalculator = () => {
  const [state, setState] = useState([""]);

  function userHeightHandler(value) {

    for (var i = 0; i < value.length; i  ) {
  
      if (value[i].length == 1) {

         var res = value.splice(1, 0, ".");

         setState(res.join(""));
      
      }

    }
    setState(value);

    return (
     
    <View style={styleInside.heightContentValue}>
          <Text style={{ justifyContent: "center", fontSize: 22 }}>
            {"text: "   state  }
          </Text>
    </View>

    <View style={styles.input}>
          <Input
            style={styles.inputs}
            placeholder="text"
            maxLength={3}
            onChangeText={(value) => userHeightHandler([value])}
            }
          />
        </View>

    
    
    )

}

My goal is to be able to concatenate a "." after the first character the user types, and have this value remain until removed, how could I do this? It may seem like a simple thing, but it's taken me all day trying to figure it out, I'd appreciate any advice or help in advance.

CodePudding user response:

If I understand correctly, you want to add a "." at the end of the user input when its length is equal to one.

Try this:

const BMIcalculator = () => {
  const [state, setState] = useState([""]);

  function userHeightHandler(value) {
    value?.length === 1 ? setState(value   ".") : setState(value);
  }

  return (
    <>
      <View style={styleInside.heightContentValue}>
        <Text style={{ justifyContent: "center", fontSize: 22 }}>
          {"text: "   state}
        </Text>
      </View>

      <View style={styles.input}>
        <Input
          style={styles.inputs}
          placeholder="text"
          maxLength={3}
          value={state}
          onChangeText={(value) => userHeightHandler(value)}
        />
      </View>
    </>
  );
};

You can see a working example in React: CodeSandBox

CodePudding user response:

So if I understand correctly, what you try to achieve is to insert a '.' character after the first character of your input as long as your input has at least one character?

Here is how it could be done assuming you don't want to update the input value itself but just the state that is displayed in the Text block.

const BMIcalculator = () => {
  const [state, setState] = useState([""]);

  function userHeightHandler(value) {
    let newValue = value;
    if (value.length === 1) {
      newValue  = '.';
    } else if (value.length > 1) {
      newValue = value.charAt(0)   '.'   value.slice(1, value.length);
    }
    setState(newValue);
  }

    return (
    <>
    <View style={styleInside.heightContentValue}>
          <Text style={{ justifyContent: "center", fontSize: 22 }}>
            {"text: "   state  }
          </Text>
    </View>

    <View style={styles.input}>
          <Input
            style={styles.inputs}
            placeholder="text"
            maxLength={3}
            onChangeText={(value) => userHeightHandler(value)} // no need to wrap value with an array
            }
          />
        </View>
    </>
    )
}

Note if you want to update the input itself, you would probably need more advance stuff like handling the cursor after the user inputs the first character or handling backspace behaviour when the user presses it from behind the first character or behind the . character. Additionally you might want to add some checks so that the user can only input numbers.

If you don't care about edge case or weird caret behaviour, you can do the following:


    const BMIcalculator = () => {
      const [state, setState] = useState([""]);
    
      function userHeightHandler(value) {
        let newValue = value;
        newValue.replaceAll('.',''); // remove all `.` characters
        // then insert it at the right place
        if (newValue.length === 1) { 
          newValue  = '.';
        } else if (newValue.length > 1) {
          newValue = newValue.charAt(0)   '.'   newValue.slice(1, value.length);
        }
        setState(newValue);
      }
    
        return (
        <>
        <View style={styleInside.heightContentValue}>
              <Text style={{ justifyContent: "center", fontSize: 22 }}>
                {"text: "   state  }
              </Text>
        </View>
    
        <View style={styles.input}>
              <Input
                style={styles.inputs}
                placeholder="text"
                maxLength={4}
                value={value}
                onChangeText={(value) => userHeightHandler(value)} // no need to wrap value with an array
                }
              />
            </View>
        </>
        )
    }

  • Related