React-Native TextInput prevent default on controlled input - reactjs

So I use my state to control a text input, but when I input a character, I don't want the character to show up right away. This is what is happening:
1. I focus on text input
2. I type in a character.
3. The character quickly shows up in the text input.
4. The character quickly disappears and the value reverts back to the state because the state has not changed yet.
I am wondering how I can prevent the character from showing up in the first place if the state has not changed.
Here is a simple example:
state = {
myValue: 'hello'
}
changedText = value => {
//Nothing here yet
}
...
render(){
return(
<Input
value={this.state.myValue}
keyboardType="numeric"
onChangeText={this.highIntervalDurationChange}
/>
);
}
As you can see it's nothing complicated, I'm just trying to figure out a way to not have the pressed character not appear right away when it is pressed because currently it appears and reverts back to the state. (Obviously I will modify the state after I can figure out how to prevent default from happening.) I also tried setting editable to false and that just makes it so I can't edit it at all. Thanks!

Related

How to change the value of hidden text input box when select menu option is changed

I want to change the existing value in a hidden text input box (automatically when the box is closed) to an empty string ('') when the user chooses one of the drop down menu selections. The problem is that I can close the component with the right menu selection, but the value does not change to an empty string until I click the button a second time. Then the value becomes an empty string and I get the correct information.
I originally based the approach to that of form data being passed to/from the parent and that does not seem to work for this component. I tried using a setState() function, however, this either didn't take or I did not implement correctly. All state has been set and all other components move data around as they're supposed to.
This is the parent component that sends/receives the information from the . The "cost={dailyTransportationCost}" is supposed to send the new value to the child.
<DailyTransportationCost
cost={dailyTransportationCost}
handleTransportationCost={e => setDailyTransportationCost(e.target.value)}
/>
This is the component that needs to change to an empty string when it's closed based on the menu option (separate component)
const DailyTransportationCost = ({ cost, handleTransportationCost }) => {
return (
<div className={`${styles.containerTransportationCost}`}>
<label className={`${styles.containerLabel}`} htmlFor='dailyTransportationCost'>Daily Cost</label>
<input className={`${styles.containerInput}`}
placeholder='0.00'
id='dailyTransportationCost'
type='number'
value={cost.dailyTransportationCost}
onChange={handleTransportationCost}
/>
</div>
);
};
Thank you for your help. I've been banging around on this for a couple of days. Any suggestions will be appreciated.
me again...
I figured it out. It was a simple useEffect() and everything worked remarkably well. Just want to thank anyone who might have stopped by.
Cheers!

Updating a state array while avoid rerenders in React

I'm building a project in react native. I have a dynamic list of players, that I want the user to be able to edit.
const [players, setPlayers] = useState(['']);
function addPlayer() {
setPlayers([...players, '']);
}
...
<List>
{ players.map(player => (
<MyInput ...>
)}
</List>
What I want to achieve is this:
User enters name
User presses enter
We call addPlayer which adds a player
New input appears and gets focused on (by other functions).
What I get is this:
User enters name
User presses enter
We call addPlayer which adds a player
The Keyboard starts closing for a split second and then opens back up when the new input appears.
I have set blurOnSubmit to false on my inputs. In my opinion what happens is that the list gets rerendered, causing the keyboard to dismiss itself. Then when the setPlayers finishes executing (it's async), the focus function gets called
useEffect(() => {
if (lastRef.current) {
lastRef.current.focus();
}
}, [players]);
What is the best way to stop the list from rerendering so that the keyboard can stay open the whole time ? Thanks !
In the end I cheated, I added an input that’s sitting right outside the list. I can control whether it’s shown or not, it’s content, as well as it’s color with other state variables.
That way when a player is added the list rerenders but doesn’t affect my input, and my keyboard doesn’t move.
From a users POV it looks exactly the same as it did before, as if he’s editing items directly in the list.

MUI Textfield multiline by state (lost focus)

I'm solving a problem regarding setting up a multi-line input after clicking on it. (in default is it single line) I have created a state that I set to true on the onFocus event (I set it to false on the onBlur event). The problem is that after clicking, I immediately lose focus of the input and have to click again. Is there any solution for this?
export default function App() {
const [focus, setFocus] = React.useState(false);
return (
<TextField
type="text"
value="lollec asda sd asd as das "
onFocus={() => setFocus(true)}
onBlur={() => setFocus(false)}
multiline={focus}
rows={3}
/>
);
}
Demo: https://codesandbox.io/s/hardcore-night-vhep1?file=/src/App.js
You can accomplish your described behavior by changing...
multiline={focus}
rows={3}
to...
multiline
rows={focus ? 3 : 1}
However, this introduces a scrollbar on the input when it's not focused. Additionally, clicking on the input will focus your cursor on the first line of text (where you clicked). You probably want the cursor to focus at the end of the text.
If you're fine with the cursor being on the first line, then I would just add some styles to hide the scrollbar.
If not, you're going to need to manage a ref for the input and specifically call ref.current.focus(). Typically, this would focus at the beginning of the text, though, so you'll need to take extra steps to ensure focus is at the end. Check out this question for help with that: Send cursor to the end of input value in React

Store update doesnot reflect

I am following React & Redux. I have actions, reducers working separately. I am managing state more or less properly.
I am trying to create a ui which is having few textboxes and a button(disabled). In text boxes i had added onchange event on which it call a function
onChangeTextbox(){
}
In this function I do the following thing.
1. I update the state of the redux store.
onChangeTextbox(){
updateStateOfTextBox();
}
2.After doing this I look for whether all the text boxes, in the ui, is having something in it. If so I will enable my button to do further operations.
onChangeTextbox(){
updateStateOfTextBox();
updateStateOfButton();
}
Everything is working good except the one thing.
That one thing is as soon as I give the last empty textbox one character, the button is not enabled immediately, and when I give more character the button gets enabled. Similarly vice versa for disabling button.
The problem which I found is that when control complete its job of function updateStateOfTextBox(); and enters the updateStateOfButton(); function the state remains same. And again when render() occurs the change in state is reflected then.
I want to fix that issue and I am not getting any way out. Any solution and suggestion to this will be appreciated.
Thanks.
I found the solution to such situation.
componentsWillRecieveProps(newProps){
}
this method of the life cycle changes the game.
componentsWillRecieveProps(newProps){
newProps.state // this will give you new updated state which your action updated.
this.props.state // this will give you local or your state
// Here you can update your local state with global state
// And call the other function here as
updateStateOfButton();
}
Therefore the solution can be interpreted like
onChangeTextbox(){
updateStateOfTextBox();
}
componentsWillRecieveProps(newProps){
.
.
updateStateOfButton();
}

ReactJS: unhide + focus an input field

I would like to show and focus an input field at the same time. I am looking for advice on the most elegant way to do this.
The simplistic approach, which doesn't work, would be:
* The element that contains the input field makes some state change which unhides the input box by setting display = ''. I got this part to work.
* The element that contains the input field gets the child element, via a ref, and calls .focus() on its DOM element. This is the part that doesn't work.
I think this is because the style change (display = '') has not propagated to the real DOM, so the focus() doesn't work.
I can think of ways to fix this (the input field could have a state var isFocusing, which calls focus() only after rendering has taken place), but I would to hear if there's a more elegant way of achieving this.
Thanks!
componentDidUpdate(prevProps, prevState) is called immediately after updates are flushed to the DOM and it can be used to focus the input box at the right time.
componentDidUpdate(prevProps) {
if(!prevProps.show && this.props.show){
// We transitioned from hidden to shown. Focus the text box.
this.refs.myInput.getDOMNode().focus();
}
},
render(){
return (
<form>
<input className={this.props.show ? 'input-shown' : 'input-hidden} />
</form>
);
}
There is more info in the docs here: https://facebook.github.io/react/docs/more-about-refs.html
Use a parent child setup with your parent sending a hide prop. In the child render if (this.props.hide) return null; or return the input. Also in the child use componentWillReceiveProps(nextProps) and set focus there.

Resources