Как динамически установить переменную State во флаттере?

Я только начинаю изучать флаттер, и мне любопытно, как я могу setState() динамически во флаттере

в React Native я обычно использовал подобную функцию для динамического setState:

class foo extends React.Component{
  state = {
    username:null,
    password:null
  }

  toggleSetState(whatState, value){
    this.setState({ [whatState]: value })
  }

  render() {
    return (
      <View>
        <TextInput
          value = {this.state.username}
          onChangeText = {(text)=>{toggleSetState(username, text)}
        />
        <TextInput
          value = {this.state.password}
          onChangeText = {(text)=>{toggleSetState(password, text)}
        />
      </View>
    );
  }
}

что эквивалентно приведенному выше коду в Flutter?

Я пробовал это в Flutter, но, похоже, не работает

class _LoginFormState extends State<LoginForm> {
  String username, password;

  void ToogleState(typedata, text){
    setState(() {
      typedata = text;
    });
  }

  //Widget
  TextField(
    onChanged: (text){ToogleState(username, text); print(username);},
    decoration: InputDecoration(
      hintText: 'input username', labelText: 'Username'
    ),
  ),
}
setState предназначен для изменений состояния, которые изменяют пользовательский интерфейс, например, извлекая данные, а затем отображая их в виджеты. В вашем случае TextField уже обрабатывает большинство визуальных изменений, поэтому вам не нужно вызывать setState. Flutter — это не Reactjs.
user1462442 10.04.2019 07:10

@user1462442 user1462442 это просто простой случай, и я использую TextField в качестве примера, что вы думаете, если когда-нибудь вы столкнетесь с той же проблемой со сложным случаем и вам нужно будет справиться с этим? например, динамическая форма из API и отправка обратно на сервер

flix 10.04.2019 07:58

использовать initState и фьючерсы dartlang.org/tutorials/language/futuresdocs.flutter.io/flutter/widgets/State/initState.html Ничего сложного

user1462442 10.04.2019 16:24
1
3
5 233
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вам просто нужно создать переменную для хранения значения. Я смущен, почему вы вызываете setState, когда вы не изменяете эфемерное состояние

Вот несколько полезных документов https://flutter.dev/docs/development/data-and-backend/state-mgmt/ephemeral-vs-app

class _LoginFormState extends State<LoginForm> {
  String _username = "";
  String __password = "";
  void ToogleState( text){
    setState(() {
      _username = text;
    });
  }

  //Widget
  TextField(
    onChanged: (text){ToogleState( text); print(username);},
    decoration: InputDecoration(
      hintText: 'input username', labelText: 'Username'
    ),
  ),
}

Если вам нужен пример фьючерсов, вот аналогичный вопрос. stackoverflow.com/questions/53820419/… Flutter проще, чем Reactjs. У вас не должно быть особых проблем

user1462442 10.04.2019 06:45

так что случилось, если у меня есть 10 TextField как регистрационная форма? я должен объявить ToogleState 10 раз для каждой переменной (имя, дата, пол и т. д.)?

flix 10.04.2019 06:47

Вам не нужно каждый раз писать toogleState. Вместо этого вы можете использовать лямбда-функцию. На самом деле, вам, вероятно, вообще не нужно вызывать setState в этом случае, поскольку TextField уже обрабатывает изменения текста.

user1462442 10.04.2019 06:49

можете ли вы привести пример лямбда-функция?

flix 10.04.2019 06:50
stackoverflow.com/questions/52404206/…
user1462442 10.04.2019 06:54

думал, что это трудно понять, но мне все еще нужно обрабатывать динамическую переменную, поэтому мне не нужно каждый раз писать одно и то же setState только с разными переменными

flix 10.04.2019 06:57
setState говорит фреймворку перестроить дерево виджетов docs.flutter.io/flutter/widgets/State/setState.html Вы можете изменить внутреннее состояние, не указывая виджету перестроить себя.
user1462442 10.04.2019 07:00
Ответ принят как подходящий

после некоторых исследований и попыток я могу добиться того, чего хочу, с помощью кода ниже:

class _LoginFormState extends State<LoginForm> {
  String username, password;
  //create an object
  var loginForm = {};
  final myController = TextEditingController();

  void ToogleState(typedata, text){
    setState(() {
      //i can assign any different variable with this code
      loginForm[typedata] = text;
      //output of LoginForm: {username: foo, password: bar}
    });
  }

  //widget
  Padding(
    padding: const EdgeInsets.all(16.0),
    child: Column(
      children: <Widget>[
        TextField(
          onEditingComplete: (){print(loginForm);},
          onChanged: (text){ToogleState("username", text); print(loginForm['username']);},
          decoration: InputDecoration(
            hintText: 'input username', labelText: 'Username'
          ),
        ),
        TextField(
          onEditingComplete: (){print(loginForm);},
          onChanged: (text){ToogleState("password", text); print(loginForm['password']);},
          decoration: InputDecoration(
            hintText: 'input password', labelText: 'Password'
          ),
        ),
      ],
    ),
  );
}

Другие вопросы по теме