reset value of text input in Vue - vue.js

I am trying to build a reset button by following the instructions for "key-changing" as shown in this blog post. Here is the code:
<template>
<view>
<text-input
:style="{ borderColor: 'gray', borderWidth: 1, backgroundColor: 'white', padding: 10, margin: 5, textAlign: 'right' }"
v-model="testInput"
keyboardType="decimal-pad"
:componentKey="componentKey"
/>
<button title="reset" :on-press="reset"/>
</view>
</template>
<script>
export default {
data() {
return {
componentKey: 0,
testInput: '14'
}
},
methods: {
reset() {
this.componentKey += 1;
console.log('parent ' + this.componentKey);
}
}
}
</script>
When initially rendered a text box appears with the value 14 inside. When the user types more digits in, it changes, as expected. However, when the user clicks the Reset button nothing happens. What ever the last number was that the user entered is still displayed. I would've expected the number in the text box to be reset to 14. The reset method is being called and the componentKey is incrementing correctly everytime the Reset button is clicked because this is visible:
parent 1
parent 2
parent 3
parent 4
parent 5
This example shows what appears in the console for 5 button presses. So why isn't the value in the text box being reset to 14?

It happens because in the memory testInput is already what is changed
reset() {
this.componentKey += 1;
this.testInput = 14; //ADD THIS
console.log('parent ' + this.componentKey);
}

Related

Mobx React `autorun` called more times on every change

I've setup a simple app store with a single numeric value, which I increment on every button click. My UI is simple: a single app <div> which contains a MyChild component that renders the number next to an increment button.
The app's autorun seems to behave correctly BUT every time I increment the value, MyChild's autorun fire extra times i.e. on page load it fires once. If I click the button, it fires twice. I click again, it fires 3 times, and so on. I expect that on every increment, autorun would fire once. What am I missing here?
Code is available on CodeSandbox
Here it is here as well:
import "./styles.css";
import * as React from "react";
import { observer } from "mobx-react-lite";
import { action, autorun, makeAutoObservable } from "mobx";
class AppStore {
v;
constructor() {
this.v = 0;
makeAutoObservable(this);
}
}
const appStore = new AppStore();
const MyChild = observer(() => {
console.log("MyChild render", appStore.v);
autorun(() => { // <------------------------ this gets fired extra times
console.log("mychild autorun " + appStore.v);
});
return (
<div style={{ backgroundColor: "lightBlue" }}>
mychild {appStore.v}
{": "}
<button
onClick={action(() => {
appStore.v += 1;
})}
>
INC
</button>
</div>
);
});
export default observer(function App() {
console.log("app render");
autorun(() => {
console.log("app autorun " + appStore.v);
});
return (
<>
<div style={{ backgroundColor: "gray", padding: "10px" }}>
main
<MyChild />
</div>
</>
);
})
I have found the reason (I'm new to Mobx-React, guess I should have figured it out)
According to this tip, I need to setup autorun inside a useEffect that happens on first render. I changed all my autoruns to:
React.useEffect(() => {
return autorun(...);
}, []);
and now they get fired once every render.

How to not leave button in selected state after click - fluent-ui (office ui fabric)

Using DefaultButton currently. This remains selected when clicked, which property can be used to revoke selection once clicked.
Alternatively, is there any styling that needs to be done for selection?
You can use DefaultButton checked property for that scenario and control it with onClick event:
const [isButtonChecked, setIsButtonChecked] = React.useState(false);
<DefaultButton
checked={isButtonChecked}
onClick={() => {
setIsButtonChecked(!isButtonChecked);
}}
styles={{
rootChecked: {
backgroundColor: '#f00',
color: '#fff',
}
}}
>
Default Button
</DefaultButton>
Use styles property to modify button styles when button state is checked: rootChecked, rootCheckedHovered etc.
Codepen example.

Limiting column width in datagrid for command button columns

in React-Admin I want to limit the width of the columns that show edit, show buttons in the datagrid
I know I can use styles to set the width of other cells like TextFields, but cant find a way to do this with buttons
enter image description here
Inside Datagrid you can use the headerClassName cellClassName props to style both the cell in the header row and in body rows as described in the docs under section Datagrid/CSS-Api
<ShowButton
headerClassName={classes.hiddenOnSmallScreens}
cellClassName={classes.hiddenOnSmallScreens}
/>
*EDIT
Obviously this approach doesn't work when using typescript, probably a bug - you can work around it in this way:
const usePostListActionToolbarStyles = makeStyles({
toolbar: {
alignItems: "center",
display: "flex",
marginTop: -1,
marginBottom: -1
}
});
const PostListActionToolbar = ({ children, ...props }) => {
const classes = usePostListActionToolbarStyles();
return (
<div className={classes.toolbar}>
{Children.map(children, (button) => cloneElement(button, props))}
</div>
);
};
and then inside your Datagrid:
<Datagrid>
//...fields
<PostListActionToolbar>
<ShowButton/>
<EditButton/>
</PostListActionToolbar>
</Datagrid>

How can i change the hover style of a PrimaryButton in Fluent UI?

I am currently trying to re-style a Fabric UI Button in React by changing its shape, background color and hovering color. I managed to change the first two, but i'm still having troubles in accessing the hover color, since the selectors property does not seem to work.
My code is the following:
import React, { Component, Props } from 'react';
import { PrimaryButton as FluentPrimaryButton, IButtonStyles, IStyle} from 'office-ui-fabric-react';
interface MyPrimaryButtonProps {
label?: string
}
const MyPrimaryButton = ({label}: MyPrimaryButtonProps) => {
const styles: IButtonStyles = {
root: [
{
fontSize: '16px',
background: '#525CA3 ',
border: '1px solid #525CA3',
borderRadius: '20px',
padding: '0px 30px',
height: '40px',
selectors: { // <---
':hover': { // <--- this part doesn't work.
backgroundColor: 'red' // <---
},
}
}
]
};
return (
<div>
<FluentPrimaryButton styles={styles} text={label} />
</div>
);
};
export default MyPrimaryButton;
I get a custom button, but still the hover color remains default blue, instead of switching to red.
You can change the styling of the button when hovered like this:
const btnStyles = {
rootHovered: {
backgroundColor: "red"
}
};
// ...
<FluentPrimaryButton text = {label} styles = {btnStyles} />;

How to make setState update before other function with useState

I am building a form to confirm the pin code of telephone number after user entered it.
I started code with
const [code, setCode] = useState("");
and I use Smooth pin code input like that
<SmoothPinCodeInput
cellStyle={{
width: 50,
borderBottomWidth: 2,
borderColor: "gray"
}}
cellStyleFocused={{
borderColor: "black"
}}
animated
onFulfill={() =>
{
setIsCodeCompleted(true)
confirmUserPin()
}
}
value={code}
onTextChange={code => setCode(code)}
/>
the problem is that setCode(code) works after confirmUsePin() that is called with onFilfill() so my pin code is 4 numbers but only 3 numbers get sent, this happend because setCode doesn't update code immediately.
I solved it, I used useEffect so every time length of code is 4 it calls the function. Here is how
useEffect( () =>{
if(code.length == 4){
confirmUserPin()
}
}, [code] )