Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как передать функцию? (https://javascript.ru/forum/misc/86049-kak-peredat-funkciyu.html)

acvafor 17.08.2024 14:09

Как передать функцию?
 
Как передать функцию?
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Settings" component={Settings} />


Хочу из home передать в settings функцию и установить в ней новые значения

Home
export default function HomeScreen() {
  const [taskList, setTaskList] = useState<Array<Item>>([]);
  const navigation = useNavigation();
  const goToMessageScreen = () => {
      navigation.navigate('Settings', {
          setTaskList,
      });
  };
}

<Button title="Submit" onPress={goToMessageScreen} color="green" />


Settings
const Settings = () => {
    const route = useRoute();
    const taskClear = () => {
        route.params.setTaskList("")
    }
    return (
        <View style={styles.container}>
            <Text style={styles.title}>
                <Button title="Submit" onPress={taskClear} color="green"/>
            </Text>
        </View>
    );
};


Срабатывает но выдаёт предупреждение
his can break usage such as persisting and restoring state. This might happen if you passed non-serializable values such as function, class instances etc. in params. If you need to use components with callbacks in your options, you

Aetae 17.08.2024 16:33

Проблема описана в тексте предупреждения.

А о взаимодействии компонентов уже 100500 раз написано.
Надо передать что-то из компонента А в компонент Б:
1. Если компонент Б лежит в компоненте А - используйте props.
2. Если компонент Б лежит в одном родителе с компонентом A - родитель слушает событие компонента А, меняет state и передаёт его в props компонента Б.
3. В любых иных случаях используется context. (в особо сложных - сторонний store)

acvafor 17.08.2024 19:26

Цитата:

Сообщение от Aetae (Сообщение 555999)
Проблема описана в тексте предупреждения.

А о взаимодействии компонентов уже 100500 раз написано.
Надо передать что-то из компонента А в компонент Б:
1. Если компонент Б лежит в компоненте А - используйте props.
2. Если компонент Б лежит в одном родителе с компонентом A - родитель слушает событие компонента А, меняет state и передаёт его в props компонента Б.
3. В любых иных случаях используется context. (в особо сложных - сторонний store)

Извините, я видимо что-то не понимаю

Не могли бы на моём примере продемонстрировать?

Aetae 17.08.2024 19:53

Пункт 3 в упрощённом виде. Как создавать и использовать контекст можете почитать сами.
export default function HomeScreen() {
  const taskListContext = useContext(TaskListContext);
  const [taskList, setTaskList] = useState<Array<Item>>([]);
  const navigation = useNavigation();

  taskListContext.setTaskList = setTaskList;

  const goToMessageScreen = () => {
      navigation.navigate('Settings');
  };
}


const Settings = () => {
    const taskListContext = useContext(TaskListContext);
    const route = useRoute();
    const taskClear = () => {
        taskListContext?.setTaskList("")
    }
    return (
        <View style={styles.container}>
            <Text style={styles.title}>
                <Button title="Submit" onPress={taskClear} color="green"/>
            </Text>
        </View>
    );
};

acvafor 17.08.2024 21:05


Я читал про контексты
Но проблема в том что
Home находится в HomeScreen.tsx
А Settings в Settins.tsx

Единственное что их связывает это app.tsx
import { useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from './tabs/HomeScreen';
import Settings from './tabs/Settings';
import {Button} from "react-native";

const Stack = createNativeStackNavigator();


export default function App() {
  return (
      <NavigationContainer>
        <Stack.Navigator
            screenOptions={{
              headerStyle: {
                backgroundColor: 'gray',
              },
              headerTintColor: '#fff',
            }}>
          <Stack.Screen name="Home" component={HomeScreen} options={{ headerShown: false }} />
          <Stack.Screen name="Settings" component={Settings} options={{ title: "",  }} />
        </Stack.Navigator>
      </NavigationContainer>
  );
}

Aetae 17.08.2024 23:43

import { useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from './tabs/HomeScreen';
import Settings from './tabs/Settings';
import {Button} from "react-native";

const Stack = createNativeStackNavigator();
const [taskListContext, setTaskListContext] = useState({setTaskList(){console.warn('setTaskList is not set')}});
taskListContext.set = setTaskListContext; // на случай полного обновления контекста

export default function App() {
  return (
    <TaskListContext.Provider value={taskListContext}>
      <NavigationContainer>
        <Stack.Navigator
            screenOptions={{
              headerStyle: {
                backgroundColor: 'gray',
              },
              headerTintColor: '#fff',
            }}>
          <Stack.Screen name="Home" component={HomeScreen} options={{ headerShown: false }} />
          <Stack.Screen name="Settings" component={Settings} options={{ title: "",  }} />
        </Stack.Navigator>
      </NavigationContainer>
    </TaskListContext.Provider>
  );
}

acvafor 18.08.2024 11:09

Цитата:

Сообщение от Aetae (Сообщение 556008)
import { useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from './tabs/HomeScreen';
import Settings from './tabs/Settings';
import {Button} from "react-native";

const Stack = createNativeStackNavigator();
const [taskListContext, setTaskListContext] = useState({setTaskList(){console.warn('setTaskList is not set')}});
taskListContext.set = setTaskListContext; // на случай полного обновления контекста

export default function App() {
  return (
    <TaskListContext.Provider value={taskListContext}>
      <NavigationContainer>
        <Stack.Navigator
            screenOptions={{
              headerStyle: {
                backgroundColor: 'gray',
              },
              headerTintColor: '#fff',
            }}>
          <Stack.Screen name="Home" component={HomeScreen} options={{ headerShown: false }} />
          <Stack.Screen name="Settings" component={Settings} options={{ title: "",  }} />
        </Stack.Navigator>
      </NavigationContainer>
    </TaskListContext.Provider>
  );
}

Откуда здесь берётся setTaskList и TaskListContext ?

Aetae 18.08.2024 21:08

acvafor, сорян, перед сном неглядя нафигачил, надо так:
import { useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from './tabs/HomeScreen';
import Settings from './tabs/Settings';
import {Button} from "react-native";

const Stack = createNativeStackNavigator();
const defaultTaskContext = {setTaskList(){console.warn('setTaskList is not set')}};
const TaskListContext = createContext(defaultTaskContext);

export default function App() {
  const [taskListContext, setTaskListContext] = useState({...defaultTaskContext});
  taskListContext.set = setTaskListContext; // на случай полного обновления контекста

  return (
    <TaskListContext.Provider value={taskListContext}>
      <NavigationContainer>
        <Stack.Navigator
            screenOptions={{
              headerStyle: {
                backgroundColor: 'gray',
              },
              headerTintColor: '#fff',
            }}>
          <Stack.Screen name="Home" component={HomeScreen} options={{ headerShown: false }} />
          <Stack.Screen name="Settings" component={Settings} options={{ title: "",  }} />
        </Stack.Navigator>
      </NavigationContainer>
    </TaskListContext.Provider>
  );
}


А setTaskList будет установлено в HomeScreen - 6 строчка.

acvafor 19.08.2024 21:22

Цитата:

Сообщение от Aetae (Сообщение 556015)
acvafor, сорян, перед сном неглядя нафигачил, надо так:
import { useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from './tabs/HomeScreen';
import Settings from './tabs/Settings';
import {Button} from "react-native";

const Stack = createNativeStackNavigator();
const defaultTaskContext = {setTaskList(){console.warn('setTaskList is not set')}};
const TaskListContext = createContext(defaultTaskContext);

export default function App() {
  const [taskListContext, setTaskListContext] = useState({...defaultTaskContext});
  taskListContext.set = setTaskListContext; // на случай полного обновления контекста

  return (
    <TaskListContext.Provider value={taskListContext}>
      <NavigationContainer>
        <Stack.Navigator
            screenOptions={{
              headerStyle: {
                backgroundColor: 'gray',
              },
              headerTintColor: '#fff',
            }}>
          <Stack.Screen name="Home" component={HomeScreen} options={{ headerShown: false }} />
          <Stack.Screen name="Settings" component={Settings} options={{ title: "",  }} />
        </Stack.Navigator>
      </NavigationContainer>
    </TaskListContext.Provider>
  );
}


А setTaskList будет установлено в HomeScreen - 6 строчка.

Благодарю


Часовой пояс GMT +3, время: 22:22.