How do I setState from toggle checkbox? - react-native

The setState is not working when I am trying to use the onToggle from the checkbox to set the state to true.
I have tried to console log the function and it works except that the state won't change.
import CircleCheckBox, { LABEL_POSITION } from 'react-native-circle-checkbox';
const MyTaskItem = (props) => {
return (
<CircleCheckBox
checked={props.taskDone}
onToggle={props.onToggleCheck}
/>
);
};
import MyTaskItem from "../../components/MyTaskItem";
export default function MyTasksScreen() {
const [taskDone, setTaskDone] = useState(false);
const checkDoneHandler = () => {
setTaskDone(true);
console.log(setTaskDone);
};
return (
<View style={styles.screen}>
<MyTaskInput visible={isAddMode} onAddTask={addTaskHandler} onCancel={cancelTaskAdditionHandler} />
<FlatList
keyExtractor={(item, index) => item.id}
data={myTasks}
renderItem={itemData =>
<MyTaskItem
id={itemData.item.id}
onDelete={removeTaskHandler}
title={itemData.item.title}
description={itemData.item.description}
onToggleCheck={checkDoneHandler}
/>}
/>
<AddTodoButton onPress={() => setIsAddMode(true)} />
</View>
);
}
I want to change the state on taskDone to true/false when toggling the checkbox.

I guess you want to change specific task state, so first of all, you need to pass the ID of the task which toggled, so MyTaskItem can be rewritten like this:
const MyTaskItem = (props) => {
const {taskDone, id, onToggleCheck} = props;
return (
<CircleCheckBox
checked={taskDone}
onToggle={()=>onToggleCheck(id)}
/>
);
};
Then you should handle items states in your MyTasksScreen.
Since FlatList is a PureComponent, therefore you need to pass the changing states to the extraData property of the flatlist, to inform item states has changed.
In case you want to change all items done state, you can do like this:
export default function MyTasksScreen() {
const [taskDone, setTaskDone] = useState(false);
const checkDoneHandler = () => {
setTaskDone(true);
console.log(setTaskDone);
};
return (
<View style={styles.screen}>
<MyTaskInput visible={isAddMode} onAddTask={addTaskHandler} onCancel={cancelTaskAdditionHandler} />
<FlatList
keyExtractor={(item, index) => item.id}
data={myTasks}
extraData={taskDone}
renderItem={itemData =>
<MyTaskItem
id={itemData.item.id}
onDelete={removeTaskHandler}
taskDone={taskDone}
title={itemData.item.title}
description={itemData.item.description}
onToggleCheck={checkDoneHandler}
/>}
/>
<AddTodoButton onPress={() => setIsAddMode(true)} />
</View>
);
}

I'd advise you to use TypeScript.
From the code you've added, looks like you're not sending taskDone to your MyTaskItem Component.
Also, try adding console.log(taskDone) after this line: const [taskDone, setTaskDone] = useState(false);

Related

Update array React native

I try to update the name in my data array with the value I get from my selected name in my flatlist.
So here I select the name in my flatlist, If I print the selected name in the terminal it print out the selected name, so that works fine.
const [name, setName] = useState();
<FlatList
numColumns={1}
horizontal={false}
data={players}
renderItem={({item}) => (
<View>
<PlayersListCard
playersName={item.name}
deleteIcon="add-circle-outline"
click={() => {
setModalVisiblePlayer(false), setName(item.name);
}}
/>
</View>
)}
/>
And here I try to set the new value (name)
const updateArray = (index) => (e) => {
let newArr = [...data];
newArr[index] = name;
setData(newArr);
};
And here I try to print out the name in my draggable item (renderText)
{
data.map((item, key, index) => (
<Draggable
x={10}
y={200}
key={key}
renderColor="blue"
renderSize={50}
onShortPressRelease={() => setModalVisiblePlayer(true)}
isCircle
textcolor="#000000"
renderText={() => updateArray(index)}
onDragRelease={(e) => {
setItemPosition(key, e.nativeEvent.pageX, e.nativeEvent.pageY);
console.log(item.X);
console.log(item.Y);
}}
/>
));
}
But their is something that I do wrong, can anyone see what?

Is there a way to set a state with textinput when onChangeText is already in use?

Im trying to set a state with the values from a textinput (which is a reusable component), Im using onChangeText to setFieldValue (useFormikContext()), I also want to set a state which will be sending to the Parent component. I tried using onChange but noticed it saves the text without the last word/number, for instance if I type 0123456789, the setFieldValue gets 0123456789, but the other one (with onChange) gets only 012345678 (without 9).
Here is the code:
function AppFormField({ name, width, childToParent, ...otherProps }) {
const { setFieldTouched, setFieldValue, errors, touched, values } =
useFormikContext();
return (
<>
<TextInput
onBlur={() => setFieldTouched(name)}
onChangeText={(text) => setFieldValue(name, text)}
onChange={() => childToParent(bn)}
value={values[name]}
width={width}
{...otherProps}
/>
<ErrorMessage error={errors[name]} visible={touched[name]} />
</>
);
}
Parent Component:
...
const [bn, setBN] = useState("");
const childToParent = (childdata) => {
setBN(childdata);
console.log(childdata);
};
console.log("bn");
console.log(bn);
...
return (
...
<UppFormField
keyboardType="numeric"
autoCorrect={false}
// icon="bank"
name="acct_number"
placeholder="Account Number"
style={{ paddingRight: 50 }}
childToParent={childToParent}
/>
...
)
Make a middle function called
const onTextChange = (text) => {
setFieldValue(text)
parentFunction(text)
}
then TextInput takes has
onChangeText={onTextChange}

Entering input causes modal reloading automatically

In my React Native 0.62.3 app, a modal is used to collect user input. Here is the view code:
import { Modal, View, TextInput, Button } from 'react-native';
const [price, setPrice] = useState(0);
const [shippingCost, setShippingCost] = useState(0);
const ReturnModal = () => {
if (isModalVisible) {
return (
<View style={styles.modalContainer}>
<Modal visible={isModalVisible}
animationType = {"slide"}
transparent={false}
onBackdropPress={() => setModalVisible(false)}>
<View style={styles.modal}>
<Text>Enter Price</Text>
<TextInput keyboardType={'number-pad'} onChange={priceChange} value={price} autoFocus={true} placeholder={'Price'} />
<TextInput keyboardType={'number-pad'} onChange={shChange} value={shippingCost} placeholder={'SnH'} />
<View style={{flexDirection:"row"}}>
<Button title="Cancel" style={{bordered:true, backgroundColor:'red'}} onPress={modalCancel} />
<Button title="OK" style={{bordered:true, backgroundColor:'white'}} onPress={modalOk} />
</View>
</View>
</Modal>
</View>
)
} else {
return (null);
}
}
return (
<Container style={styles.container}>
//.....view code
<ReturnModal />
</Container>
)
Here is 2 functions to reset state of price and shippingCost:
const priceChange = (value) => {
if (parseFloat(value)>0) {
setPrice(Math.ceil(parseFloat(value)));
}
};
const shChange = (value) => {
if (parseFloat(value)>=0) {
setShippingCost(Math.ceil(parseFloat(value)));
}
};
The problem is that whenever entering in the price field with keystroke, the modal reloads/resets itself automatically. Tried onChangeText in TextInput and it has the same problem.
It seems like you're declaring your hooks outside your component. Try putting them inside your ReturnModal function instead, like this:
const ReturnModal = () => {
const [price, setPrice] = useState(0);
const [shippingCost, setShippingCost] = useState(0);
...
Documentation reference: Using the State Hook.
Also, I would strongly recommend using the React Hooks ESLint Plugin (among others) to detect issues with your hooks. Here is a guide on how to add this to your React Native project: Add Eslint Support to your React Native Project + React Hooks Rules.
Instead of using animationType = {"slide"} try using animatonType : 'none'

Flat list not showing anything even though data and render is provided

I have a flatlist inside a component like so:
const MyInvestments = (props) => {
return (
<SafeAreaView>
<Text style={styles.myInvestments}>
My Investments
</Text>
<FlatList
data={props.investments}
renderItem={renderInvestment}
keyExtractor={item => item.id}
/>
</SafeAreaView>
);
}
and props.investments is the following:
[{name:"investment1", id:"23423"},
{name:"investment2", id: "32423"}]
However, the flatlist items, the investment1 and investment2 are not getting displayed on the screen whereas they are supposed to show up as items of the flatlist. How to fix this?
renderInvestment looks like the following:
const renderInvestment = (props) => {
<View>
<Text>Investment</Text>
<Text>{props.name}</Text>
</View>
}
A couple of things you can try.
Use capitalized const for RenderInvestment
Return a JSX from RenderInvestment function like this:
const RenderInvestment = (props) => (
<View>
<Text>Investment</Text>
<Text>{props.name}</Text>
</View>
)

React-native FlatList component is Not Working

Hello I am a beginner to react-native. I was practicing with a basic app which reads the input from the user and display it in the screen. I am trying to use the FlatList but it is not rendering.
Here is my code
export default function App() {
const [enteredText, setEnteredText] = useState(
""
); /* constant and method with String*/
const [enteredString, setEnteredString] = useState(
[]
); /* constant and method with Array */
const enteredTextHandler = (enteredText) => {
setEnteredText(enteredText);
}; /* Set the entered text to the constant value*/
const addTextHandler = () => {
setEnteredString((currentString) => [
...currentString,
{ id: Math.random().toString(), value: enteredText },
]); /* Add entered text to the array */
};
return (
<View style={styles.mainView}>
<View style={styles.container}>
<TextInput
placeholder="Enter te value"
style={styles.input}
onChangeText={enteredTextHandler}
value={enteredText}
/>
<Button title="Add" onPress={addTextHandler} style={styles.button} />
</View>
<FlatList
data={enteredString}
keyExtractor={(item) => item.id}
renderItem={(itemData) => {
console.log(itemData.item.value);
<View style={styles.listStyle}>
<Text>{itemData.item.value}</Text>
</View>;
}}
/>
</View>
);
}
It might be because you've reused the variable name enteredText in your enteredTextHandler. I think the way it's set up it'll always set enteredText to blank.
Try using a different name for the text argument:
const enteredTextHandler = newText => {
setEnteredText(newText);
}; /* Set the entered text to the constant value*/
I got the answer
<FlatList
data={enteredString}
keyExtractor={(item, index) => item.id}
renderItem={(itemData) => (
<View style={styles.listStyle}>
<Text>{itemData.item.value}</Text>
</View>
)}
/>
I was written the syntax wrong. previously I used (itemData) => {} but the actual syntax is (itemData) => () . Instead of parantesis I used curly braces that's why it was not displaying.