skip to Main Content

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.

3

Answers


  1. 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

    Login or Signup to reply.
  2. 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 = newValue.replaceAll(".", ""); // remove all `.` characters
        // then insert it at the right place
        // second condition is to allow backspace on `.` character
        if (newValue.length === 1 && !(value.length === 1 && state.length === 2)) {
          newValue += ".";
        } else if (newValue.length > 1) {
          // insert '.' after first character, then add the rest of the value
          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>
        </>
      );
    };
    
    Login or Signup to reply.
  3. Both, using a [""] for your state and your userHeightHandler look way too complicated to me.

    My goal is to be able to concatenate a "." after the first character the user types, and have this value remain until removed

    something like this?

    const input = document.getElementById("foo");
    let prev = input.value;
    
    input.oninput = e => {
      let value = e.target.value;
      value = (prev === value + ".") ? "" : value.replace(/D+/g, "");
      e.target.value = prev = value && value[0] + "." + value.slice(1,3);
    }
    <input id="foo">

    this shouldn’t be too hard to translate to react. something like

    const [state, setState] = useState("");
    
    onChangeText={value => setState(prev => (prev === value + ".") ? "" : (value = value.replace(/D+/g, "")) && value[0] + "." + value.slice(1,3))}
    

    You even get prev for free when doing setState(prev => ...)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search