如何从“静态导航选项”访问组件的状态?

时间:2021-07-26 18:58:34

How do you handle cases when you have, say, a form component, and you need to submit a part of the component's state using button in navigation bar?

当您有一个表单组件,并且需要在导航栏中使用按钮提交组件的一部分状态时,您如何处理这些情况?

const navBtn = (iconName, onPress) => (
  <TouchableOpacity
    onPress={onPress}
    style={styles.iconWrapper}
  >
    <Icon name={iconName} size={cs.iconSize} style={styles.icon} />
  </TouchableOpacity>
)

class ComponentName extends Component {

  static navigationOptions = {
    header: (props) => ({
      tintColor: 'white',
      style: {
        backgroundColor: cs.primaryColor
      },
      left: navBtn('clear', () => props.goBack()),
      right: navBtn('done', () => this.submitForm()), // error: this.submitForm is not a function
    }),
    title: 'Form',
  }

  constructor(props) {
    super(props);
    this.state = {
      formText: ''
    };
  }

  submitForm() {
    this.props.submitFormAction(this.state.formText)
  }

  render() {
    return (
      <View>
        ...form goes here
      </View>
    );
  }
}

4 个解决方案

#1


9  

Send a binded function with setParams, then you will have access to component's state within that function.

使用setParams发送绑定的函数,然后您将访问该函数中的组件状态。

Example:

例子:

constructor(props) {
    super(props);
    this._handleButtonNext = this._handleButtonNext.bind(this);
    this.state = { selectedIndex: 0 }
}

componentDidMount() {
    this.props.navigation.setParams({
        handleButtonNext: this._handleButtonNext,
    });
}

_handleButtonNext() {
    let action = NavigationActions.setParams({
        params: { selectedImage: images[this.state.selectedIndex] }
    });
    this.props.navigation.dispatch(action);
}

Now you can have a button handler related to component's state.

现在您可以拥有一个与组件状态相关的按钮处理程序。

static navigationOptions = ({ navigation }) => {
    const { state, setParams, navigate } = navigation;
    const params = state.params || {};

    return {
        headerTitleStyle: { alignSelf: 'center' },
        title: 'Select An Icon',
        headerRight: <Button title='Next' onPress={params.handleButtonNext} />
    }
}

#2


9  

Simple Design Pattern

Just as a follow-up to @val's excellent answer, here's how I structured my Component so that all the params are set in the componentWillMount. I find this keeps it simpler and is an easy pattern to follow for all other screens.

作为@val优秀答案的后续,下面是我如何构建组件的结构,以便在componentWillMount中设置所有参数。我发现这使它更简单,并且对于所有其他屏幕来说都是一个容易遵循的模式。

static navigationOptions = ({navigation, screenProps}) => {
  const params = navigation.state.params || {};

  return {
    title:       params.title,
    headerLeft:  params.headerLeft,
    headerRight: params.headerRight,
  }
}

_setNavigationParams() {
  let title       = 'Form';
  let headerLeft  = <Button onPress={this._clearForm.bind(this)} />;
  let headerRight = <Button onPress={this._submitForm.bind(this)} />;

  this.props.navigation.setParams({ 
    title,
    headerLeft,
    headerRight, 
  });
}

componentWillMount() {
  this._setNavigationParams();
}

_clearForm() {
  // Clear form code...
}

_submitForm() {
  // Submit form code...
}

#3


1  

On your componentDidMount, you can use

在您的componentDidMount上,您可以使用

this.navigation.setParams({
 myTitle: this.props.myTitle
})

Then, pass a function to your header on static props. This function has access to the params you set before

然后,在静态道具上向你的标题传递一个函数。这个函数可以访问您以前设置的参数

Thanks to rafaelcorreiapoli

由于rafaelcorreiapoli

#4


-3  

You are getting this error because you are using props and state before declaring constructor() . As in constructor we first call super(props) so that we can use props in our component. Please do the following to get desired result.

您会得到这个错误,因为您在声明构造函数()之前使用了道具和状态。在构造函数中,我们首先调用super(道具),以便在组件中使用道具。请做下面的操作以得到期望的结果。

constructor(props) {
    super(props);
    this.state = {
      formText: ''
    };

  static navigationOptions = {
    header: (props) => ({
      tintColor: 'white',
      style: {
        backgroundColor: cs.primaryColor
      },
      left: navBtn('clear', () => props.goBack()),
      right: navBtn('done', () => this.submitForm()), // error: this.submitForm is not a function
    }),
    title: 'Form',
  }
  }

Cheers:)

欢呼:)

#1


9  

Send a binded function with setParams, then you will have access to component's state within that function.

使用setParams发送绑定的函数,然后您将访问该函数中的组件状态。

Example:

例子:

constructor(props) {
    super(props);
    this._handleButtonNext = this._handleButtonNext.bind(this);
    this.state = { selectedIndex: 0 }
}

componentDidMount() {
    this.props.navigation.setParams({
        handleButtonNext: this._handleButtonNext,
    });
}

_handleButtonNext() {
    let action = NavigationActions.setParams({
        params: { selectedImage: images[this.state.selectedIndex] }
    });
    this.props.navigation.dispatch(action);
}

Now you can have a button handler related to component's state.

现在您可以拥有一个与组件状态相关的按钮处理程序。

static navigationOptions = ({ navigation }) => {
    const { state, setParams, navigate } = navigation;
    const params = state.params || {};

    return {
        headerTitleStyle: { alignSelf: 'center' },
        title: 'Select An Icon',
        headerRight: <Button title='Next' onPress={params.handleButtonNext} />
    }
}

#2


9  

Simple Design Pattern

Just as a follow-up to @val's excellent answer, here's how I structured my Component so that all the params are set in the componentWillMount. I find this keeps it simpler and is an easy pattern to follow for all other screens.

作为@val优秀答案的后续,下面是我如何构建组件的结构,以便在componentWillMount中设置所有参数。我发现这使它更简单,并且对于所有其他屏幕来说都是一个容易遵循的模式。

static navigationOptions = ({navigation, screenProps}) => {
  const params = navigation.state.params || {};

  return {
    title:       params.title,
    headerLeft:  params.headerLeft,
    headerRight: params.headerRight,
  }
}

_setNavigationParams() {
  let title       = 'Form';
  let headerLeft  = <Button onPress={this._clearForm.bind(this)} />;
  let headerRight = <Button onPress={this._submitForm.bind(this)} />;

  this.props.navigation.setParams({ 
    title,
    headerLeft,
    headerRight, 
  });
}

componentWillMount() {
  this._setNavigationParams();
}

_clearForm() {
  // Clear form code...
}

_submitForm() {
  // Submit form code...
}

#3


1  

On your componentDidMount, you can use

在您的componentDidMount上,您可以使用

this.navigation.setParams({
 myTitle: this.props.myTitle
})

Then, pass a function to your header on static props. This function has access to the params you set before

然后,在静态道具上向你的标题传递一个函数。这个函数可以访问您以前设置的参数

Thanks to rafaelcorreiapoli

由于rafaelcorreiapoli

#4


-3  

You are getting this error because you are using props and state before declaring constructor() . As in constructor we first call super(props) so that we can use props in our component. Please do the following to get desired result.

您会得到这个错误,因为您在声明构造函数()之前使用了道具和状态。在构造函数中,我们首先调用super(道具),以便在组件中使用道具。请做下面的操作以得到期望的结果。

constructor(props) {
    super(props);
    this.state = {
      formText: ''
    };

  static navigationOptions = {
    header: (props) => ({
      tintColor: 'white',
      style: {
        backgroundColor: cs.primaryColor
      },
      left: navBtn('clear', () => props.goBack()),
      right: navBtn('done', () => this.submitForm()), // error: this.submitForm is not a function
    }),
    title: 'Form',
  }
  }

Cheers:)

欢呼:)