UseState Hook trong React Native

UseState là một hook trong react và cũng được sử dụng đối với app trong react native. Đây là một hook dùng để thay đổi trạng thái của dữ liệu. UseState được sử dụng dưới dạng function component được khai báo như sau.

1. Import UseState từ thư viên React

import React, {useState } from "react";

2. khởi tạo UseState

const [state, setState] = useState(initialStateValue)
  • state: định nghĩa tên của state nó có thể là đơn giá trị hoặc object,.. (là một tham số của useState)
  • setState: định nghĩa tên function dùng cho việc update state (là một  tham số của useState). setState là một dạng callback Funtion với giá trị trả về chính là giá trị mới cho state.
  • initialStateValue: là giá trị ban đầu của state. initialStateValue luôn là 1 giá trị. hoặc nếu là 1 function thì initialStateValue sẽ luôn nhận giá trị là giá trị trả về của funtion đó.

3. Ví dụ:

3.1 Sử dụng UseState trong ứng dụng đếm số.

import { StatusBar } from "expo-status-bar";
import { useState } from "react";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";

const order = [100, 200, 300];

export default function UseStateCounter() {
    const total = order.reduce((total, current) => total + current, 0);
    // const [counter, setCounter] = useState(total);
    const [counter, setCounter] = useState(
        order.reduce((total, current) => total + current, 0)
    );
    const handleIncrement = () => {
        setCounter((prevState) => prevState + 1);
    };

    console.log("re-render");
    return (
        <View style={styles.container}>
            <Text style={styles.h1}>{counter}</Text>
            <TouchableOpacity style={styles.button} onPress={handleIncrement}>
                <Text style={styles.buttonText}>Increment</Text>
            </TouchableOpacity>
        </View>
    );
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: "#fff",
        alignItems: "center",
        justifyContent: "center",
    },
    h1: {
        fontSize: 30,
        fontWeight: "bold",
        margin: 20,
    },
    button: {
        backgroundColor: "blue",
        width: "80%",
        height: 50,
        justifyContent: "center",
        alignItems: "center",
    },
    buttonText: {
        color: "white",
        fontSize: 20,
        fontWeight: "bold",
    },
});

3.1 Sử dụng UseState trong ứng dụng ramdon quà tặng

import { StatusBar } from "expo-status-bar";
import { useState } from "react";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";

const gifts = ["CPU i9", "Ram 32GB RGB", "RGB Keyboard"];

export default function UseStateExam() {
    const [gift, setGift] = useState();

    const randomGift = () => {
        let index = Math.floor(Math.random() * gifts.length);
        setGift(gifts[index]);
    };

    return (
        <View style={styles.container}>
            <Text style={styles.h1}>{gift || "Chưa có phần thưởng"}</Text>
            <TouchableOpacity style={styles.button} onPress={randomGift}>
                <Text style={styles.buttonText}>Increment</Text>
            </TouchableOpacity>
        </View>
    );
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: "#fff",
        alignItems: "center",
        justifyContent: "center",
    },
    h1: {
        fontSize: 30,
        fontWeight: "bold",
        margin: 20,
    },
    button: {
        backgroundColor: "blue",
        width: "80%",
        height: 50,
        justifyContent: "center",
        alignItems: "center",
    },
    buttonText: {
        color: "white",
        fontSize: 20,
        fontWeight: "bold",
    },
});

3.1 Sử dụng UseState một số phần tử của form

import { StatusBar } from "expo-status-bar";
import { useState } from "react";
import { RadioButton, Checkbox } from "react-native-paper";
import {
    StyleSheet,
    Text,
    TextInput,
    TouchableOpacity,
    View,
} from "react-native";

//Response from API server
const courses = [
    { id: 1, name: "HTML, CSS" },
    { id: 2, name: "JavaScript" },
    { id: 3, name: "ReactJS" },
    { id: 4, name: "ReactNative" },
];

export default function UseStateExam2() {
    const [name, setName] = useState("");
    const [email, setEmail] = useState("");
    const [checked, setChecked] = useState("");
    const [checkedBox, setCheckedBox] = useState([]);

    const handleSubmit = () => {
        console.log({
            name,
            email,
            checked,
            checkedBox,
        });
    };

    const handleCheckRadio = (id) => {
        setChecked(id);
    };

    const handleCheckedBox = (id) => {
        if (checkedBox.includes(id)) {
            let newCheckedBox = checkedBox.filter((item) => item != id);
            setCheckedBox(newCheckedBox);
        } else {
            setCheckedBox((prev) => [...prev, id]);
        }
    };

    return (
        <View style={styles.container}>
            <Text style={styles.h1}>{name}</Text>
            <TextInput
                value={name}
                style={styles.textInput}
                onChangeText={(value) => setName(value)}
            />
            <TextInput
                value={email}
                style={styles.textInput}
                onChangeText={(value) => setEmail(value)}
            />
            <View style={styles.boxButtons}>
                {courses.map((course, index) => {
                    return (
                        <TouchableOpacity
                            onPress={() => handleCheckRadio(course.id)}
                            key={`courses_${index}`}
                            style={styles.radioButtonBox}
                        >
                            <RadioButton
                                value={course.id}
                                style={styles.radioButton}
                                status={checked === course.id ? "checked" : ""}
                            />
                            <Text>{course.name}</Text>
                        </TouchableOpacity>
                    );
                })}
            </View>
            <View style={styles.boxButtons}>
                {courses.map((course, index) => {
                    return (
                        <TouchableOpacity
                            onPress={() => handleCheckedBox(course.id)}
                            key={`courses_${index}`}
                            style={styles.radioButtonBox}
                        >
                            <Checkbox
                                status={
                                    checkedBox.includes(course.id)
                                        ? "checked"
                                        : "unchecked"
                                }
                            />
                            <Text>{course.name}</Text>
                        </TouchableOpacity>
                    );
                })}
            </View>

            <TouchableOpacity style={styles.button} onPress={handleSubmit}>
                <Text style={styles.buttonText}>Register</Text>
            </TouchableOpacity>
        </View>
    );
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: "#fff",
        alignItems: "center",
        justifyContent: "center",
        padding: 20,
    },
    h1: {
        fontSize: 30,
        fontWeight: "bold",
        margin: 20,
    },
    button: {
        backgroundColor: "blue",
        width: "80%",
        height: 50,
        justifyContent: "center",
        alignItems: "center",
    },
    buttonText: {
        color: "white",
        fontSize: 20,
        fontWeight: "bold",
    },
    textInput: {
        backgroundColor: "white",
        borderColor: "grey",
        borderWidth: 1,
        width: "100%",
        minHeight: 50,
        padding: 10,
        marginBottom: 10,
    },
    radioButtonBox: {
        flexDirection: "row",
        alignItems: "center",
    },
    boxButtons: {
        flexDirection: "row",
        flexWrap: "wrap",
        borderWidth: 1,
        borderColor: "grey",
        marginBottom: 20,
    },
});

Leave a Reply